🐱💻 Создание простого GraphQL Server с нуля 👨💻
Начнем с ответа на простой вопрос: что такое GraphQL?
GraphQL - очень мощный язык запросов, который используется для эффективного взаимодействия между клиентом и сервером. В отличие от SQL, который представляет собой сборку языка уровня данных для получения данных из реляционной базы данных, GraphQL - это язык запросов уровня приложения, который позволяет нам получать данные непосредственно с сервера. или API и позволяет использовать более гибкий и эффективный подход, чем REST.
Зачем мне изучать GraphQL, если я могу использовать подход RESTful? 🤷
Представьте, что в вашем распоряжении имеется следующая конечная точка REST.
mycompanydomain.org/employees
Вы хотели бы получить конкретную информацию о ваших сотрудниках, такую как его / ее имя, адрес электронной почты, должность и отдел, в котором он / она работает. При традиционном подходе, таком как REST, вы должны выполнить вызов AJAX к конечной точке, сервер после получения запроса возвращает полную информацию о ресурсе, включая другие детали, такие как номер телефона, пол, дату присоединения и всю хрень, которую вы никогда не спрашивали для. Проблема здесь в том, что при настройке REST API большую часть времени вы теряете информацию, независимо от того, что вам нужно. Это приводит к потере полосы пропускания и других ресурсов и требует больших затрат на серверы.
На помощь приходит GraphQL! Это дает нам именно то, что мы хотим, и не более того. Помимо этого, синтаксис запросов в GraphQL очень похож на представление наших данных. Еще одно преимущество использования GraphQL заключается в том, что вы можете получать данные из нескольких ресурсов в одном запросе, что позволяет сэкономить еще больше ресурсов.
🗣 Как сделать запрос GraphQL?
Из вышесказанного видно, что в GraphQL очень просто делать запросы, а синтаксис похож на план данных. В приведенном выше примере нам просто нужны имя сотрудника, адрес электронной почты, должность и имя / имена проекта, частью которого он является, и сервер просто отвечает, передавая только эти биты информации.
GraphiQL 🎀 - интерфейсный инструмент запросов для тестирования нашего сервера GraphQL.
По умолчанию GraphQL поставляется с графическим интерфейсом пользователя, который помогает нам тестировать наши запросы на сервере. Это удобный инструмент, который запускается в браузере и состоит из 3 разделов, краткое описание которых вы можете увидеть выше. Он обладает такими замечательными функциями, как подсветка синтаксиса, обработка ошибок, автоматизация и подсказки. Самый левый раздел - это место, где вы можете писать запросы; средний раздел показывает ответ сервера, а крайний правый раздел - проводник документации, который показывает нам карту наших данных и описывает схему наших запросов.
📝План действий:
Мы создадим простой сервер GraphQL, используя Node и Express, выполнив следующие 5 шагов:
- Настройте бэкэнд с помощью Node и Express.
- Создать схему и корневой запрос
- Реализация CRUD-операций с использованием Axios и JSON-сервера
- Тестирование с GraphiQL
- Мутации
👆Шаг 1:
- Создайте новую папку на своем компьютере и назовите ее «GraphQL_sandbox».
- Используя командную строку, CD в только что созданную папку «GraphQL_sandbox».
- Убедитесь, что на вашем компьютере установлен Node.js, и введите следующую команду:
npm init
- Вам будет предложено несколько простых вопросов, вы можете ответить на них или проигнорировать их. После завершения этого шага Node.js создаст файл манифеста с именем package.json, который будет отслеживать ваши зависимости.
- Используйте следующую команду, чтобы получить необходимые пакеты: express, graphql и express-graphql.
npm i express graphql express-graphql nodemon
- Это создаст запись в файле package.json в зависимостях. Итак, что это за пакеты:
express: это один из самых популярных и легких фреймворков для создания веб-сервера.
graphql: пакет, который позволяет нам создавать схему типа и обслуживать запросы по этой схеме типа.
express-graphql: этот пакет действует как промежуточное ПО между express и graphql.
nodemon: помогает разрабатывать приложения на основе node.js путем автоматического перезапуска приложения node при обнаружении изменений файлов в каталоге.
- Внутри package.json создайте запись в разделе «scripts» для запуска nodemon. Должно быть так 👇
- Создайте файл и назовите его server.js, который будет действовать как точка входа для нашего приложения. Добавьте следующий код в server.js.
const express = require("express"); const graphqlHTTP = require("express-graphql"); const schema = require('./schema'); const app = express(); // MIDDLEWARE app.use("/graphql", graphqlHTTP({ schema: schema, graphiql: true })); app.listen(5000, () => console.log("Server running on port 5000"));
Если вы работали с экспресс-версией, то вы должны быть знакомы с большей частью приведенного выше кода. graphqlHTTP
здесь действует как промежуточное программное обеспечение и требует объекта конфигурации со схемой, которая состоит из запросов и изменений (мы обсудим позже); graphiql: true
позволит нам использовать инструмент GraphiQL для тестирования наших запросов.
✌️ Шаг 2:
- Создайте файл и назовите его schema.js (упоминается в server.js), он будет содержать все наши запросы и изменения.
const graphql = require("graphql"); // PART 1 - ES6 DESTRUCTURING const { GraphQLObjectType, GraphQLString, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLSchema } = graphql; // PART 2 - EMPLOYEE TYPE const EmployeeType = new GraphQLObjectType({ name: "Employee", fields: () => ({ id: { type: GraphQLInt } name: { type: GraphQLString }, email: { type: GraphQLString }, age: { type: GraphQLInt } }) }); // PART 3 - ROOT QUERY const RootQuery = new GraphQLObjectType({ name: "RootQueryType", fields: { employee: { type: EmployeeType, args: { id: { type: GraphQLInt } }, resolve(parentValue, args) { // Code to get data from server } } } }); // PART 4 - EXPORT SCHEMA module.exports = new GraphQLSchema({ query: RootQuery });
- Часть 1. Пакет
graphql
позволяет нам определять схему, которая соответствует официальной спецификации и определениям. Он отвечает за синтаксический анализ нашей схемы и преобразование ее в объект JS. Этот пакет поставляется с определениями типов, которые помогут нам проверить наши поля. - Часть 2 - Схемы помогают нам описать, как выглядят данные в нашем запросе, они состоят из типов объектов и отношений между этими объектами, а также описывают, как мы можем связаться с сервером для извлечения / изменения данных.
- Часть 3 - Корневой запрос - это способ описать, как пользователь может попасть на сервер для извлечения и получения данных. Это объект, который описывает, какие конечные точки доступны клиенту.
- Часть 4 - Наконец, мы экспортируем нашу схему, на которую мы ссылались в нашей точке входа, где она передается промежуточному программному обеспечению.
👌Шаг 3:
- У нас есть готовая схема и корневой запрос, но нам нужны данные, с которыми можно поиграть. Для этого необходимо установить два пакета - JSON-Server и Axios. JSON-Server используется для создания поддельного REST API, который мы можем использовать, а Axios - это HTTP-клиент на основе обещаний для браузера и node.js.
npm i json-server axios
- Теперь перейдите в package.json и создайте еще одну запись в сценариях, как показано ниже. Это позволяет нам запустить json-сервер, на котором размещены наши фиктивные данные.
"scripts": { "serve": "nodemon server.js"; "json:server" "json-server --watch data.json" }
- Создайте файл data.json и добавьте следующие данные.
{ "employees": [ { "id": 1, "name": "John Doe", "email": "[email protected]", "age": 32 }, { "id": 2, "name": "Kate Williams", "email": "[email protected]", "age": 50 }, { "id": 3, "name": "Linda Johnson", "email": "[email protected]", "age": 37 } ] }
- Откройте командную строку в каталоге GrapQL_sandbox и выполните следующую команду. Это по умолчанию запустит фальшивый REST API, который мы только что создали, на порту 3000.
npm run json:server
- Затем в schema.js используйте axios, который поможет нам выполнять операции CRUD с нашим поддельным API.
const axios = require('axios'); const RootQuery = new GraphQLObjectType({ name: "RootQueryType", fields: { employee: { type: EmployeeType, args: { id: { type: GraphQLInt } }, resolve(parent, args) { return axios.get(`http://localhost:3000/employees/${args.id}`) .then(res => res.data) } }, employees: { type: new GraphQLList(EmployeeType), resolve(parent, args) { return axios.get(`http://localhost:3000/employees`) .then(res => res.data) } } } });
- Откройте новый терминал, перейдите в папку GraphQL_Sandbox и введите следующую команду.
npm run serve
🤟Шаг 4:
- Откройте свой любимый браузер и перейдите в
http://localhost:5000/graphql
- Теперь вы можете использовать GraphiQL IDE, которую мы обсуждали ранее, для тестирования наших запросов. Введите следующий запрос; нажмите кнопку воспроизведения, и сервер ответит соответствующей информацией.
{ employee(id: 2) { name email } }
- Чтобы получить всех сотрудников 👨👩👧👧, используйте это:
{ employees { name, email, age } }
- Теперь вы успешно получили соответствующую информацию. Мы вернемся к нашей схеме и рассмотрим возможность ее расширения.
🖐Шаг 5:
- Мутации. Мутации позволяют нам изменять / вносить изменения в наши данные. Например, добавление нового сотрудника, редактирование существующей записи сотрудника, удаление записи сотрудника - все это может быть выполнено с помощью мутаций. В GraphQL нам нужно явно определить наши мутации, чтобы указать, какие данные можно добавлять, редактировать, удалять и т. Д.
- Под нашим корневым запросом в schema.js добавьте следующий код:
// MUTATIONS const mutation = new GraphQLObjectType({ name: "Mutation", fields: { addEmployee: { type: EmployeeType, args: { name: { type: new GraphQLNonNull(GraphQLString) }, email: { type: new GraphQLNonNull(GraphQLString) }, age: { type: new GraphQLNonNull(GraphQLInt) } }, resolve(parent, args) { return axios .post(`http://localhost:3000/employees/`, { name: args.name, email: args.email, age: args.age }).then(res => res.data); } }, editEmployee: { type: EmployeeType, args: { name: { type: GraphQLString }, email: { type: GraphQLString }, age: { type: GraphQLInt }, id: { type: new GraphQLNonNull(GraphQLInt) } }, resolve(parent, args) { return axios.patch(`http://localhost:3000/employees/${args.id}`, args) .then(res => res.data); } }, deleteEmployee: { type: EmployeeType, args: { id: { type: new GraphQLNonNull(GraphQLInt) } }, resolve(parentValue, args) { return axios.delete(`http://localhost:3000/employees/${args.id}`) .then(res => res.data); } } } }); module.exports = new GraphQLSchema({ query: RootQuery, mutation: mutation });
- Перейдите на
http://localhost:5000/graphql
, чтобы изменить наши фиктивные данные. - Чтобы проверить, добавьте нового сотрудника, набрав следующий код и нажав кнопку воспроизведения. Теперь вы должны убедиться, что у вашего поддельного API есть новая запись.
mutation { addEmployee(name:"Raj Kapoor", email:"[email protected]", age: 23){ name email age } }
- Чтобы 🤹♂️ обновить запись сотрудника:
mutation { editEmployee(id: 3, age: 40){ name email age } }
- Чтобы ❌ удалить запись о сотруднике:
mutation { deleteEmployee(id: 2){ id } }
🙌 Поздравляем, вы успешно создали простой сервер GraphQL и выполнили операции CRUD.