GraphQL е агностик на базата данни, така че можете да използвате всичко, което обикновено използвате за взаимодействие с базата данни, и да използвате resolve
на заявката или мутацията метод за извикване на функция, която сте дефинирали, която ще получи/добави нещо към базата данни.
Без реле
Ето пример за мутация, използваща базирания на обещания конструктор на заявки Knex SQL, първо без Relay, за да усетите концепцията. Предполагам, че сте създали userType във вашата GraphQL схема, която има три полета:id
, username
и created
:всичко задължително и че имате getUser
вече дефинирана функция, която прави заявки към базата данни и връща потребителски обект. В базата данни имам и password
колона, но тъй като не искам това да бъде запитано, го оставям извън моя userType
.
// db.js
// take a user object and use knex to add it to the database, then return the newly
// created user from the db.
const addUser = (user) => (
knex('users')
.returning('id') // returns [id]
.insert({
username: user.username,
password: yourPasswordHashFunction(user.password),
created: Math.floor(Date.now() / 1000), // Unix time in seconds
})
.then((id) => (getUser(id[0])))
.catch((error) => (
console.log(error)
))
);
// schema.js
// the resolve function receives the query inputs as args, then you can call
// your addUser function using them
const mutationType = new GraphQLObjectType({
name: 'Mutation',
description: 'Functions to add things to the database.',
fields: () => ({
addUser: {
type: userType,
args: {
username: {
type: new GraphQLNonNull(GraphQLString),
},
password: {
type: new GraphQLNonNull(GraphQLString),
},
},
resolve: (_, args) => (
addUser({
username: args.username,
password: args.password,
})
),
},
}),
});
Тъй като Postgres създава id
за мен и аз изчислявам created
времева марка, не ми трябват в заявката ми за мутация.
Пътят на щафетата
Използване на помощниците в graphql-relay
и придържането доста близо до Relay Starter Kit ми помогна, защото беше много за приемане наведнъж. Relay изисква да настроите вашата схема по специфичен начин, за да може да работи правилно, но идеята е същата:използвайте функциите си, за да извличате или добавяте към базата данни в методите за разрешаване.
Едно важно предупреждение е, че Relay начинът очаква, че обектът е върнат от getUser
е екземпляр на клас User
, така че ще трябва да модифицирате getUser
за да посрещне това.
Последният пример с използване на Relay (fromGlobalId
, globalIdField
, mutationWithClientMutationId
и nodeDefinitions
всички са от graphql-relay
):
/**
* We get the node interface and field from the Relay library.
*
* The first method defines the way we resolve an ID to its object.
* The second defines the way we resolve an object to its GraphQL type.
*
* All your types will implement this nodeInterface
*/
const { nodeInterface, nodeField } = nodeDefinitions(
(globalId) => {
const { type, id } = fromGlobalId(globalId);
if (type === 'User') {
return getUser(id);
}
return null;
},
(obj) => {
if (obj instanceof User) {
return userType;
}
return null;
}
);
// a globalId is just a base64 encoding of the database id and the type
const userType = new GraphQLObjectType({
name: 'User',
description: 'A user.',
fields: () => ({
id: globalIdField('User'),
username: {
type: new GraphQLNonNull(GraphQLString),
description: 'The username the user has selected.',
},
created: {
type: GraphQLInt,
description: 'The Unix timestamp in seconds of when the user was created.',
},
}),
interfaces: [nodeInterface],
});
// The "payload" is the data that will be returned from the mutation
const userMutation = mutationWithClientMutationId({
name: 'AddUser',
inputFields: {
username: {
type: GraphQLString,
},
password: {
type: new GraphQLNonNull(GraphQLString),
},
},
outputFields: {
user: {
type: userType,
resolve: (payload) => getUser(payload.userId),
},
},
mutateAndGetPayload: ({ username, password }) =>
addUser(
{ username, password }
).then((user) => ({ userId: user.id })), // passed to resolve in outputFields
});
const mutationType = new GraphQLObjectType({
name: 'Mutation',
description: 'Functions to add things to the database.',
fields: () => ({
addUser: userMutation,
}),
});
const queryType = new GraphQLObjectType({
name: 'Query',
fields: () => ({
node: nodeField,
user: {
type: userType,
args: {
id: {
description: 'ID number of the user.',
type: new GraphQLNonNull(GraphQLID),
},
},
resolve: (root, args) => getUser(args.id),
},
}),
});