Создание API-интерфейсов GraphQL с помощью Node
Опубликовано: 2022-12-20GraphQL — новое модное слово в разработке API. Хотя API-интерфейсы RESTful остаются наиболее популярным способом предоставления данных из приложений, они имеют множество ограничений, которые GraphQL стремится устранить.
GraphQL — это язык запросов, созданный Facebook, который в 2015 году превратился в проект с открытым исходным кодом. Он предлагает интуитивно понятный и гибкий синтаксис для описания и доступа к данным в API.
В этом руководстве рассказывается, как создать проект GraphQL Node.js. Мы будем использовать GraphQL для создания приложения Todo в веб-фреймворке Express.js для Node.
Что такое GraphQL?
Из официальной документации: «GraphQL — это язык запросов для API и среда выполнения для выполнения этих запросов с вашими существующими данными. GraphQL предоставляет полное и понятное описание данных в вашем API, дает клиентам возможность запрашивать именно то, что им нужно, и ничего больше, упрощает разработку API с течением времени и предоставляет мощные инструменты для разработчиков».
GraphQL — это среда выполнения на стороне сервера для выполнения запросов с использованием системы типов, которую вы определили для своих данных. Кроме того, GraphQL не привязан к какой-либо конкретной базе данных или механизму хранения. Вместо этого он поддерживается вашим существующим кодом и хранилищем данных. Подробное сравнение этих технологий можно найти в руководстве GraphQL vs. RESTful API.
Чтобы создать службу GraphQL, вы начинаете с определения типов схемы и создания полей с использованием этих типов. Затем вы предоставляете преобразователь функции, который будет выполняться для каждого поля, и вводите его каждый раз, когда данные запрашиваются на стороне клиента.
Терминология GraphQL
Система типов GraphQL используется для описания того, какие данные можно запрашивать и какими данными можно манипулировать. Это ядро GraphQL. Давайте обсудим различные способы описания и обработки данных в GraphQ.
Типы
Типы объектов GraphQL — это модели данных, содержащие строго типизированные поля. Между вашими моделями и типами GraphQL должно быть сопоставление 1-к-1. Ниже приведен пример типа GraphQL:
type User { id: ID! # The "!" means required firstname: String lastname: String email: String username: String todos: [Todo] # Todo is another GraphQL type }
Запросы
Запрос GraphQL определяет все запросы, которые клиент может выполнять в API GraphQL. Вы должны определить RootQuery , который по соглашению будет содержать все существующие запросы.
Ниже мы определяем и сопоставляем запросы с соответствующим RESTful API:
type RootQuery { user(id: ID): User # Corresponds to GET /api/users/:id users: [User] # Corresponds to GET /api/users todo(id: ID!): Todo # Corresponds to GET /api/todos/:id todos: [Todo] # Corresponds to GET /api/todos }
Мутации
Если запросы GraphQL — это запросы GET , мутации — это запросы POST , PUT , PATCH и DELETE , которые манипулируют API GraphQL.
Мы поместим все мутации в одну RootMutation , чтобы продемонстрировать:
type RootMutation { createUser(input: UserInput!): User # Corresponds to POST /api/users updateUser(id: ID!, input: UserInput!): User # Corresponds to PATCH /api/users removeUser(id: ID!): User # Corresponds to DELETE /api/users createTodo(input: TodoInput!): Todo updateTodo(id: ID!, input: TodoInput!): Todo removeTodo(id: ID!): Todo }
Вы заметили использование типов -input для мутаций, таких как UserInput , TodoInput . Всегда рекомендуется всегда определять типы ввода для создания и обновления ваших ресурсов.
Вы можете определить типы ввода , как показано ниже:
input UserInput { firstname: String! lastname: String email: String! username: String! }
Резольверы
Резолверы сообщают GraphQL, что делать, когда запрашивается каждый запрос или мутация. Это базовая функция, которая выполняет тяжелую работу по обращению к уровню базы данных для выполнения операций CRUD (создание, чтение, обновление, удаление), обращению к внутренней конечной точке RESTful API или вызову микрослужбы для выполнения запроса клиента.
Вы можете создать новый файл resolvers.js и добавить следующий код:
import sequelize from '../models'; export default function resolvers () { const models = sequelize.models; return { // Resolvers for Queries RootQuery: { user (root, { id }, context) { return models.User.findById(id, context); }, users (root, args, context) { return models.User.findAll({}, context); } }, User: { todos (user) { return user.getTodos(); } }, } // Resolvers for Mutations RootMutation: { createUser (root, { input }, context) { return models.User.create(input, context); }, updateUser (root, { id, input }, context) { return models.User.update(input, { ...context, where: { id } }); }, removeUser (root, { id }, context) { return models.User.destroy(input, { ...context, where: { id } }); }, // ... Resolvers for Todos go here } }; }
Схема
Схема GraphQL — это то, что GraphQL открывает миру. Таким образом, типы, запросы и мутации будут включены в схему, чтобы быть доступными для всего мира.
Ниже показано, как выставлять типы, запросы и мутации миру:
schema { query: RootQuery mutation: RootMutation }
В приведенном выше сценарии мы включили RootQuery и RootMutation , созданные нами ранее, чтобы показать их миру.
Как GraphQL работает с Nodejs и Expressjs
GraphQL предоставляет реализацию для всех основных языков программирования, и Node.js не является исключением. На официальном сайте GraphQL есть раздел поддержки JavaScript, а также есть другие реализации GraphQL, упрощающие написание и кодирование в GraphQL.
GraphQL Apollo предоставляет реализацию для Node.js и Express.js и упрощает начало работы с GraphQL.
В следующем разделе вы узнаете, как создать и разработать свое первое приложение GraphQL в бэкэнд-фреймворке Nodes.js и Express.js с использованием GraphQL Apollo.
Настройка GraphQL с помощью Express.js
Создать сервер GraphQL API с помощью Express.js очень просто. В этом разделе мы рассмотрим, как создать сервер GraphQL.
Инициализировать проект с помощью Express
Во-первых, вам нужно установить и настроить новый проект Express.js.
Создайте папку для своего проекта и установите Express.js с помощью этой команды:
cd <project-name> && npm init -y npm install express
Приведенная выше команда создает новый файл package.json и устанавливает библиотеку Express.js в ваш проект.
Далее мы структурируем наш проект, как показано на изображении ниже. Он будет содержать различные модули для функций проекта, таких как пользователи, задачи и т. д.
Инициализировать GraphQL
Начнем с установки зависимостей GraphQL Express.js. Выполните следующую команду для установки:
npm install apollo-server-express graphql @graphql-tools/schema --save
Создание схем и типов
Далее мы создадим файл index.js внутри папки модулей и добавим следующий фрагмент кода:
const { gql } = require('apollo-server-express'); const users = require('./users'); const todos = require('./todos'); const { GraphQLScalarType } = require('graphql'); const { makeExecutableSchema } = require('@graphql-tools/schema'); const typeDefs = gql` scalar Time type Query { getVersion: String! } type Mutation { version: String! } `; const timeScalar = new GraphQLScalarType({ name: 'Time', description: 'Time custom scalar type', serialize: (value) => value, }); const resolvers = { Time: timeScalar, Query: { getVersion: () => `v1`, }, }; const schema = makeExecutableSchema({ typeDefs: [typeDefs, users.typeDefs, todos.typeDefs], resolvers: [resolvers, users.resolvers, todos.resolvers], }); module.exports = schema;
Пошаговое руководство по коду
Давайте проработаем фрагмент кода и разберем его:
Шаг 1
Во-первых, мы импортировали необходимые библиотеки и создали типы запросов и мутаций по умолчанию. Запрос и мутация пока устанавливают только версию GraphQL API. Однако мы расширим запрос и мутацию, чтобы включить другие схемы по мере продвижения.
Шаг 2:
Затем мы создали новый скалярный тип для времени и наш первый преобразователь для запроса и мутации, созданных выше. Кроме того, мы также сгенерировали схему с помощью функции makeExecutableEchema .
Сгенерированная схема включает в себя все другие схемы, которые мы импортировали, а также будет включать больше, когда мы их создадим и импортируем.
Приведенный выше фрагмент кода показывает, что мы импортировали разные схемы в функцию makeExecutableEchema. Такой подход помогает нам структурировать приложение по сложности. Далее мы создадим импортированные схемы Todo и User.
Создание схемы Todo
Схема Todo показывает простые операции CRUD, которые могут выполнять пользователи приложения. Ниже представлена схема, реализующая операцию Todo CRUD.
const { gql } = require('apollo-server-express'); const createTodo = require('./mutations/create-todo'); const updateTodo = require('./mutations/update-todo'); const removeTodo = require('./mutations/delete-todo'); const todo = require('./queries/todo'); const todos = require('./queries/todos'); const typeDefs = gql` type Todo { id: ID! title: String description: String user: User } input CreateTodoInput { title: String! description: String isCompleted: Boolean } input UpdateTodoInput { title: String description: String isCompleted: Boolean } extend type Query { todo(id: ID): Todo! todos: [Todo!] } extend type Mutation { createTodo(input: CreateTodoInput!): Todo updateTodo(id: ID!, input: UpdateTodoInput!): Todo removeTodo(id: ID!): Todo } `; // Provide resolver functions for your schema fields const resolvers = { // Resolvers for Queries Query: { todo, todos, }, // Resolvers for Mutations Mutation: { createTodo, updateTodo, removeTodo, }, }; module.exports = { typeDefs, resolvers };
Пошаговое руководство по коду
Давайте проработаем фрагмент кода и разберем его:
Шаг 1:
Сначала мы создали схему для нашего Todo, используя GraphQL type , input и extend . Ключевое слово extend используется для наследования и добавления новых запросов и мутаций к существующему корневому запросу и мутации, которые мы создали выше.
Шаг 2:
Затем мы создали преобразователь, который используется для извлечения правильных данных при вызове определенного запроса или мутации.
Имея функцию распознавателя, мы можем создавать отдельные методы для бизнес-логики и манипулирования базой данных, как показано в примере create-todo.js .
Создайте файл create-user.js в папке <code>./mutations</code> и добавьте бизнес-логику для создания нового Todo в вашей базе данных.
const models = require('../../../models'); module.exports = async (root, { input }, context) => { return models.todos.push({ ...input }); };
Приведенный выше фрагмент кода представляет собой упрощенный способ создания нового Todo в нашей базе данных с помощью Sequelize ORM. Вы можете узнать больше о Sequelize и о том, как его настроить с помощью Node.js.
Вы можете выполнить тот же шаг, чтобы создать множество схем в зависимости от вашего приложения, или вы можете клонировать весь проект из GitHub.
Далее мы настроим сервер с Express.js и запустим только что созданное приложение Todo с GraphQL и Node.js.
Настройка и запуск сервера
Наконец, мы настроим наш сервер, используя библиотеку apollo-server-express , которую мы установили ранее, и настроим ее.
apollo-server-express — это простая оболочка Apollo Server для Express.js. Рекомендуется, поскольку она была разработана для разработки Express.js.
Используя примеры, которые мы рассмотрели выше, давайте настроим сервер Express.js для работы с недавно установленным apollo-server-express .
Создайте файл server.js в корневом каталоге и вставьте следующий код:
const express = require('express'); const { ApolloServer } = require('apollo-server-express'); const schema = require('./modules'); const app = express(); async function startServer() { const server = new ApolloServer({ schema }); await server.start(); server.applyMiddleware({ app }); } startServer(); app.listen({ port: 3000 }, () => console.log(`Server ready at http://localhost:3000`) );
В приведенном выше коде вы успешно создали свой первый сервер CRUD GraphQL для Todos и пользователей. Вы можете запустить свой сервер разработки и получить доступ к игровой площадке, используя http://localhost:3000/graphql. Если все прошло успешно, вы должны увидеть экран ниже:
Резюме
GraphQL — это современная технология, поддерживаемая Facebook, которая упрощает утомительную работу по созданию крупномасштабных API с архитектурными шаблонами RESTful.
В этом руководстве разъясняется GraphQL и демонстрируется, как разработать свой первый API GraphQL с помощью Express.js.
Дайте нам знать, что вы строите с помощью GraphQL.