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
|
-- User data tables
|
||||||
GRANT SELECT ON openneo_impress.item_outfit_relationships TO impress2020;
|
GRANT SELECT ON openneo_impress.item_outfit_relationships TO impress2020;
|
||||||
GRANT SELECT ON openneo_impress.outfits 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
|
items: [Item!]! # deprecated alias for wornItems
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type User {
|
||||||
|
id: ID!
|
||||||
|
username: String!
|
||||||
|
}
|
||||||
|
|
||||||
type Query {
|
type Query {
|
||||||
allColors: [Color!]! @cacheControl(maxAge: 10800) # Cache for 3 hours (we might add more!)
|
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!)
|
allSpecies: [Species!]! @cacheControl(maxAge: 10800) # Cache for 3 hours (we might add more!)
|
||||||
|
@ -256,6 +261,8 @@ const typeDefs = gql`
|
||||||
color(id: ID!): Color
|
color(id: ID!): Color
|
||||||
species(id: ID!): Species
|
species(id: ID!): Species
|
||||||
|
|
||||||
|
user(id: ID!): User
|
||||||
|
|
||||||
petOnNeopetsDotCom(petName: String!): Outfit
|
petOnNeopetsDotCom(petName: String!): Outfit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,6 +612,12 @@ const resolvers = {
|
||||||
.map((oir) => ({ id: oir.itemId }));
|
.map((oir) => ({ id: oir.itemId }));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
User: {
|
||||||
|
username: async ({ id }, _, { userLoader }) => {
|
||||||
|
const user = await userLoader.load(id);
|
||||||
|
return user.name;
|
||||||
|
},
|
||||||
|
},
|
||||||
Query: {
|
Query: {
|
||||||
allColors: async (_, { ids }, { colorLoader }) => {
|
allColors: async (_, { ids }, { colorLoader }) => {
|
||||||
const allColors = await colorLoader.loadAll();
|
const allColors = await colorLoader.loadAll();
|
||||||
|
@ -688,6 +701,19 @@ const resolvers = {
|
||||||
return petStates.map((petState) => ({ id: petState.id }));
|
return petStates.map((petState) => ({ id: petState.id }));
|
||||||
},
|
},
|
||||||
outfit: (_, { id }) => ({ 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 }) => {
|
petOnNeopetsDotCom: async (_, { petName }) => {
|
||||||
const [petMetaData, customPetData] = await Promise.all([
|
const [petMetaData, customPetData] = await Promise.all([
|
||||||
neopets.loadPetMetaData(petName),
|
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 buildZoneLoader = (db) => {
|
||||||
const zoneLoader = new DataLoader(async (ids) => {
|
const zoneLoader = new DataLoader(async (ids) => {
|
||||||
const qs = ids.map((_) => "?").join(",");
|
const qs = ids.map((_) => "?").join(",");
|
||||||
|
@ -504,6 +521,7 @@ function buildLoaders(db) {
|
||||||
);
|
);
|
||||||
loaders.speciesLoader = buildSpeciesLoader(db);
|
loaders.speciesLoader = buildSpeciesLoader(db);
|
||||||
loaders.speciesTranslationLoader = buildSpeciesTranslationLoader(db);
|
loaders.speciesTranslationLoader = buildSpeciesTranslationLoader(db);
|
||||||
|
loaders.userLoader = buildUserLoader(db);
|
||||||
loaders.zoneLoader = buildZoneLoader(db);
|
loaders.zoneLoader = buildZoneLoader(db);
|
||||||
loaders.zoneTranslationLoader = buildZoneTranslationLoader(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