add basic user data to GraphQL API
This commit is contained in:
parent
4796d213aa
commit
f3013c2956
4 changed files with 108 additions and 0 deletions
|
@ -21,3 +21,4 @@ GRANT UPDATE ON openneo_impress.swf_assets TO impress2020;
|
|||
-- User data tables
|
||||
GRANT SELECT ON openneo_impress.item_outfit_relationships TO impress2020;
|
||||
GRANT SELECT ON openneo_impress.outfits TO impress2020;
|
||||
GRANT SELECT ON openneo_impress.users TO impress2020;
|
||||
|
|
|
@ -222,6 +222,11 @@ const typeDefs = gql`
|
|||
items: [Item!]! # deprecated alias for wornItems
|
||||
}
|
||||
|
||||
type User {
|
||||
id: ID!
|
||||
username: String!
|
||||
}
|
||||
|
||||
type Query {
|
||||
allColors: [Color!]! @cacheControl(maxAge: 10800) # Cache for 3 hours (we might add more!)
|
||||
allSpecies: [Species!]! @cacheControl(maxAge: 10800) # Cache for 3 hours (we might add more!)
|
||||
|
@ -256,6 +261,8 @@ const typeDefs = gql`
|
|||
color(id: ID!): Color
|
||||
species(id: ID!): Species
|
||||
|
||||
user(id: ID!): User
|
||||
|
||||
petOnNeopetsDotCom(petName: String!): Outfit
|
||||
}
|
||||
|
||||
|
@ -605,6 +612,12 @@ const resolvers = {
|
|||
.map((oir) => ({ id: oir.itemId }));
|
||||
},
|
||||
},
|
||||
User: {
|
||||
username: async ({ id }, _, { userLoader }) => {
|
||||
const user = await userLoader.load(id);
|
||||
return user.name;
|
||||
},
|
||||
},
|
||||
Query: {
|
||||
allColors: async (_, { ids }, { colorLoader }) => {
|
||||
const allColors = await colorLoader.loadAll();
|
||||
|
@ -688,6 +701,19 @@ const resolvers = {
|
|||
return petStates.map((petState) => ({ id: petState.id }));
|
||||
},
|
||||
outfit: (_, { id }) => ({ id }),
|
||||
user: async (_, { id }, { userLoader }) => {
|
||||
try {
|
||||
const user = await userLoader.load(id);
|
||||
} catch (e) {
|
||||
if (e.message.includes("could not find user")) {
|
||||
return null;
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
return { id };
|
||||
},
|
||||
petOnNeopetsDotCom: async (_, { petName }) => {
|
||||
const [petMetaData, customPetData] = await Promise.all([
|
||||
neopets.loadPetMetaData(petName),
|
||||
|
|
|
@ -425,6 +425,23 @@ const buildPetStatesForPetTypeLoader = (db, loaders) =>
|
|||
);
|
||||
});
|
||||
|
||||
const buildUserLoader = (db) => new DataLoader(async (ids) => {
|
||||
const qs = ids.map((_) => "?").join(",");
|
||||
const [rows, _] = await db.execute(
|
||||
`SELECT * FROM users WHERE id IN (${qs})`,
|
||||
ids
|
||||
);
|
||||
|
||||
const entities = rows.map(normalizeRow);
|
||||
const entitiesById = new Map(entities.map((e) => [e.id, e]));
|
||||
|
||||
return ids.map(
|
||||
(id) =>
|
||||
entitiesById.get(String(id)) ||
|
||||
new Error(`could not find user with ID: ${id}`)
|
||||
);
|
||||
});
|
||||
|
||||
const buildZoneLoader = (db) => {
|
||||
const zoneLoader = new DataLoader(async (ids) => {
|
||||
const qs = ids.map((_) => "?").join(",");
|
||||
|
@ -504,6 +521,7 @@ function buildLoaders(db) {
|
|||
);
|
||||
loaders.speciesLoader = buildSpeciesLoader(db);
|
||||
loaders.speciesTranslationLoader = buildSpeciesTranslationLoader(db);
|
||||
loaders.userLoader = buildUserLoader(db);
|
||||
loaders.zoneLoader = buildZoneLoader(db);
|
||||
loaders.zoneTranslationLoader = buildZoneTranslationLoader(db);
|
||||
|
||||
|
|
63
src/server/query-tests/User.test.js
Normal file
63
src/server/query-tests/User.test.js
Normal file
|
@ -0,0 +1,63 @@
|
|||
const gql = require("graphql-tag");
|
||||
const { query, getDbCalls } = require("./setup.js");
|
||||
|
||||
describe("User", () => {
|
||||
it("looks up a user", async () => {
|
||||
const res = await query({
|
||||
query: gql`
|
||||
query {
|
||||
user(id: "6") {
|
||||
id
|
||||
username
|
||||
}
|
||||
}
|
||||
`,
|
||||
});
|
||||
|
||||
expect(res).toHaveNoErrors();
|
||||
expect(res.data).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"user": Object {
|
||||
"id": "6",
|
||||
"username": "matchu",
|
||||
},
|
||||
}
|
||||
`);
|
||||
expect(getDbCalls()).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"SELECT * FROM users WHERE id IN (?)",
|
||||
Array [
|
||||
"6",
|
||||
],
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it("returns null when user not found", async () => {
|
||||
const res = await query({
|
||||
query: gql`
|
||||
query {
|
||||
user(id: "<invalid-user-id>") {
|
||||
id
|
||||
username
|
||||
}
|
||||
}
|
||||
`,
|
||||
});
|
||||
|
||||
expect(res).toHaveNoErrors();
|
||||
expect(res.data.user).toBe(null);
|
||||
expect(getDbCalls()).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"SELECT * FROM users WHERE id IN (?)",
|
||||
Array [
|
||||
"<invalid-user-id>",
|
||||
],
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue