По завершении этого руководства вы получите базовое представление о том, как выполнять операции создания, чтения, обновления и удаления в GraphQL API.

Что такое GraphQL?

GraphQL — это язык запросов для ваших API, который помогает приложениям запрашивать у серверов конкретную информацию. Вместо того, чтобы получать массу данных, которые вам могут не понадобиться, GraphQL позволяет приложениям запрашивать только те данные, которые им нужны. Это экономит время, ускоряет работу приложений и помогает разработчикам создавать более удобные условия для пользователей.

Преимущества GraphQL

  • Единая конечная точка. В отличие от традиционных REST API, где для разных данных может потребоваться несколько конечных точек, GraphQL обычно использует одну конечную точку, что упрощает структуру запросов.
  • Уменьшение избыточной и недостаточной выборки. Традиционные API могут отправлять слишком много или слишком мало данных, что может привести к избыточной выборке (получению большего количества данных, чем необходимо) или недостаточной выборке (неполучению достаточного количества данных). ). GraphQL устраняет эту проблему, передавая управление клиенту.
  • Данные в реальном времени.GraphQL имеет подписки — функцию, которая обеспечивает обновление данных в реальном времени, что делает ее подходящей для приложений, которым требуются оперативные данные, таких как приложения для обмена сообщениями или интерактивные информационные панели.

Предварительные условия

  1. Базовое понимание работы с Nodejs.
  2. Базовые запросы для получения данных из MongoDB/Mongoose.

Настройка GraphQL и других зависимостей

  • Структура проекта
project/
  ├── src/
  |   ├── db/
  |   |   ├── databse.js
  |   |   ├── Post.js
  |   ├── schema/
  |   |   ├── post.js
  |   ├── resolvers.js
  |   └── index.js
  └── package.json
  • Создайте новый каталог проекта и откройте его в текстовом редакторе.
  • Откройте терминал в каталоге и инициализируйте его с конфигурацией по умолчанию, используя эту команду.

npm init -y

  • Установка необходимых зависимостей.

npm install express mongoose @graphql-tools/schema express-graphql --save

  • Определите схему GraphQL.
// src/schema/post.js
const typeDefs = `

  type Post {
    _id: ID!
    title: String!
    content: String!
  }

  type Query {
    getPost(_id: ID!): Post
    getAllPosts: [Post]
  }

  type Mutation {
    createPost(title: String!, content: String!): Post
    updatePost(_id: ID!, title: String!, content: String!): Post
    deletePost(_id: ID!): Boolean
  }
`;

module.exports = typeDefs;

Схема описывает типы данных, доступных в вашем приложении. Сюда входит указание типа полей и того, как они связаны. Для определения схемы он использует специальный язык, называемый SDL (язык определения схемы).

Разберем схему…

Тип сообщения описывает структуру сообщения, включая его уникальный идентификатор, заголовок и содержание. Каждое поле в сообщении имеет определенный тип, например идентификатор! (ненулевой идентификатор) и «String!» (ненулевая строка).

Тип запроса определяет операции, которые клиенты могут использовать для получения данных. «getPost» принимает идентификатор сообщения в качестве аргумента и возвращает объект сообщения. «getAllPosts» возвращает массив всех объектов сообщений.

Тип мутации определяет операции по изменению данных. «createPost» позволяет клиентам создавать новую публикацию, указав заголовок и содержание. «updatePost» позволяет клиентам изменять существующую публикацию, предоставляя ее идентификатор, новый заголовок и новое содержание. «deletePost» позволяет клиентам удалять сообщение, указав его идентификатор.

  • Создайте схему сообщения для базы данных.
// src/db/Post.js
const { Schema, model } = require('mongoose');

const postSchema = new Schema({
    title: String,
    content:  String
});

const Post = model('Post', postSchema);

module.exports = Post

Mongoose — это популярная библиотека сопоставления объектных данных (ODM) для Node.js и MongoDB. Он обеспечивает более удобный и структурированный способ работы с MongoDB.

  • Установление соединения MongoDB.
// src/db/databse.js
const mongoose = require('mongoose');

const DB_URL = 'mongodb+srv://<dbuser>:<dbpassword>@<MongoDB_URI>';

mongoose.connect(DB_URL, { useNewUrlParser: true })

mongoose.connection.on('open', () => {
  console.log('MongoDB connected Successfully!')
});

Я бы порекомендовал вам использовать MongoDB Atlas, который представляет собой облачную службу баз данных, предоставляемую MongoDB.

Замените <dbuser>, <dbpassword> и <MongoDB_URI> своими учетными данными или добавьте URL-адрес локальной базы данных.

  • Создание файла резольвера.
// src/resolver.js
const Post = require('./db/Post');

const resolvers = {
  Query: {
    // Implement your query resolvers here
    getAllPosts: async() => {
   try {
    const result = await Post.find({});
    if(!result.length){
     throw new Error("No Posts Added!")
    }
    return result;
   } catch (error) {
    throw error;
   }
  },
  getPost: async(_, args) => {
   try {
    const result = await Post.findById(args._id);
    if(!result){
     throw new Error("Post does not exists!")
    }
    return result
   } catch (error) {
    throw error
   }
  },
  },
  Mutation: {
    // Implement your mutation resolvers here
    createPost: async(_, args ) => {  
   try { 
    const result = await Post.create({ 
     title: args.title, 
     content: args.content 
    });
    return result
   } catch (error) {
    throw error
   }
  },
  updatePost: async(_, args) => {
   try {
    const result = await Post.findByIdAndUpdate(args._id, {
     title: args.title,
     content: args.content
    }, { new: true });
    if(!result){
     throw new Error("Post does not exists!")
    }
    return result
   } catch (error) {
    throw error
   }
  },
  deletePost: async(_, args) => {
   try {
    const result = await Post.findByIdAndDelete(args._id);
    if(!result) {
     return false
    }
    return true
   } catch (error) {
    throw error
   }
  },
  },
};

module.exports = resolvers;

Резолверы отвечают за получение фактических данных, когда клиент отправляет запрос или выполняет мутацию.

Распознаватель запросов извлекает данные из базы данных, а преобразователь мутаций изменяет данные в базе данных.

Каждый преобразователь может дополнительно принимать четыре позиционных аргумента: (parent, args, context, info)

  1. parent: этот объект используется в более сложных случаях, когда у вас есть вложенные структуры данных или в определенных преобразователях, поэтому его часто обозначают подчеркиванием (_), чтобы указать, что он не используется.
  2. args: этот параметр означает «аргументы». Он содержит значения, переданные в типе Query или Mutation.
  3. контекст: этот параметр обеспечивает доступ к общим данным и ресурсам, которые могут потребоваться различным преобразователям. Это часто используется для таких вещей, как аутентификация или подключение к базе данных.
  4. информация: этот объект содержит информацию о самом запросе и запрошенных полях. Обычно он не используется в большинстве резольверов.
  • Создание файла сервера.
// src/index.js
const express = require("express");
const  { graphqlHTTP } = require("express-graphql");
const { makeExecutableSchema } = require('@graphql-tools/schema');
const postSchema = require('./schema/post');
const resolvers = require('./resolvers');
require('./db/database');

// makeExecutableSchema function creates a GraphQL schema with typeDefs and resolvers
const schema = makeExecutableSchema({
  typeDefs: postSchema,
  resolvers: resolvers,
});

const app = express();

app.use('/graphql', graphqlHTTP({
  schema,
  graphiql: true  //enables graphql interface in browser
}));

const PORT = 4000;

app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});

На данный момент мы завершили настройку. Вы можете посетить http://localhost:4000/graphql в своем браузере для тестирования API GraphQL.

Добавление сообщения.

Поля можно выбирать в зависимости от их использования, здесь я использовал заголовок и содержимое.

Получите сообщение.

getPost можно использовать без добавления query в начале, поскольку это операция по умолчанию.

Обновить сообщение.

Удаление сообщения.

Получить все сообщения.

Поздравляем! Вы успешно разобрались во всех тонкостях создания полноценного CRUD с использованием GraphQL, Node.js и MongoDB. К настоящему моменту вы должны быть уверены в своей способности создавать надежные API.

Удачного программирования, и пусть ваши начинания с GraphQL приведут к бесконечным инновациям! 🚀💡

Вы можете получить доступ к коду этого руководства здесь.