Мы можем создать простой сервер GraphQL с помощью Express. Для этого нам понадобятся пакеты express-graphql
и graphql
.
В этой статье мы рассмотрим, как создавать мутации и типы ввода с помощью Express и GraphQL.
Мутации и типы ввода
Чтобы создать мутации, мы создаем схему, которая имеет тип Mutation
, а не Query
.
Затем достаточно просто сделать конечную точку API частью верхнего уровня Mutation
типа вместо типа Query
.
И мутации, и запросы могут обрабатываться корневыми преобразователями.
Затем мы можем создать сервер GraphQL, который принимает как запросы, так и мутации следующим образом:
const express = require('express'); const graphqlHTTP = require('express-graphql'); const { buildSchema } = require('graphql'); const crypto = require('crypto'); const schema = buildSchema(` input TodoInput { text: String } type Todo { id: ID! text: String } type Query { getTodo(id: ID!): Todo } type Mutation { createTodo(input: TodoInput): Todo updateTodo(id: ID!, input: TodoInput): Todo } `); class Todo { constructor(id, { text }) { this.id = id; this.text = text; } } let todos = {}; const root = { getTodo: ({ id }) => { if (!todos[id]) { throw new Error('Todo not found.'); } return new Todo(id, todos[id]); }, createTodo: ({ input }) => { const id = crypto.randomBytes(10).toString('hex'); todos[id] = input; return new Todo(id, input); }, updateTodo: ({ id, input }) => { if (!todos[id]) { throw new Error('Todo not found'); } todos[id] = input; return new Todo(id, input); }, }; const app = express(); app.use('/graphql', graphqlHTTP({ schema: schema, rootValue: root, graphiql: true, })); app.listen(3000, () => console.log('server started'));
В приведенном выше коде мы определили наши типы, написав:
const schema = buildSchema(` input TodoInput { text: String } type Todo { id: ID! text: String } type Query { getTodo(id: ID!): Todo } type Mutation { createTodo(input: TodoInput): Todo updateTodo(id: ID!, input: TodoInput): Todo } `);
Мы создали тип ввода TodoInput
и тип Todo
. Затем мы создали тип Query
с членом getTodo
, чтобы мы могли получать наши задачи.
Затем в нашем Mutation
мы добавили участников createTodo
и updateTodo
, чтобы мы могли добавлять и обновлять задачи.
Затем мы создаем наш Todo
класс, чтобы мы могли хранить данные задачи:
class Todo { constructor(id, { text }) { this.id = id; this.text = text; } }
Далее у нас есть корневой резолвер:
const root = { getTodo: ({ id }) => { if (!todos[id]) { throw new Error('Todo not found.'); } return new Todo(id, todos[id]); }, createTodo: ({ input }) => { const id = crypto.randomBytes(10).toString('hex'); todos[id] = input; return new Todo(id, input); }, updateTodo: ({ id, input }) => { if (!todos[id]) { throw new Error('Todo not found'); } todos[id] = input; return new Todo(id, input); }, };
Он добавляет функции с теми же функциями, которые мы указали в нашей схеме, чтобы мы могли что-то делать при выполнении некоторых запросов.
В этом примере getTodo
мы вернем задачу с заданным id
. Будет возвращено найденное задание. В противном случае мы выдаем ошибку.
В createTodo
мы получаем input
из запроса, а затем добавляем запись задачи в наш объект todos
, который является нашей фальшивой базой данных для хранения задач. Сохраненное задание будет возвращено.
Затем у нас есть функция updateTodo
для обновления задачи на id
. Все, что имеет данный id
, будет заменено содержимым input
. Сохраненное задание будет возвращено. Мы выдаем ошибку, если задача с заданным id
не найдена.
Затем, когда мы перейдем на страницу /graphql
, мы можем ввести следующее в окно GraphiQL:
mutation { createTodo(input: {text: "eat"}) { id text } }
Тогда получаем что-то вроде:
{ "data": { "createTodo": { "id": "c141d1fda69e8d9084bd", "text": "eat" } } }
как ответ.
Если мы сделаем запрос на обновление todo следующим образом:
mutation { updateTodo(id: "e99ce10750c93793a23d", input: {text: "eat"}) { id text } }
Получаем что-то вроде:
{ "data": { "updateTodo": { "id": "e99ce10750c93793a23d", "text": "eat" } } }
назад в качестве ответа.
Если задача не найдена, получаем:
{ "errors": [ { "message": "Todo not found", "locations": [ { "line": 9, "column": 3 } ], "path": [ "updateTodo" ] } ], "data": { "updateTodo": null } }
как ответ.
Мы можем сделать getTodo
запрос следующим образом:
query { getTodo(id: "e99ce10750c93793a23d"){ id text } }
Тогда получаем:
{ "data": { "getTodo": { "id": "e99ce10750c93793a23d", "text": "eat" } } }
как ответ.
Заключение
Мы можем создавать мутации так же, как и с запросами.
Чтобы принять операции мутации на нашем сервере GraphQL, мы создаем наши типы для хранения наших данных, а затем мы создаем наши мутации, заполняя тип Mutation
нашими членами.
Затем мы можем использовать функцию buildSchema
для построения только что указанной схемы.
Затем в нашем корневом редукторе мы создаем функции с именами, которые мы указали в определениях типов.
Наконец, мы можем делать запросы к нашему серверу для запуска мутаций.
Примечание от JavaScript In Plain English:
Мы всегда заинтересованы в продвижении качественного контента. Если у вас есть статья, которую вы хотите отправить в JavaScript In Plain English, отправьте нам электронное письмо по адресу [email protected] с вашим именем пользователя Medium, и мы добавим вас в качестве автора.