Ние ще изградим пълен и напълно работещ GraphQL API, използвайки Express framework за Node с MongoDB като наша база данни.

През последното десетилетие REST се превърна в стандарт за проектиране на уеб API. REST стана по-конкретна с появата на най-добри практики за уеб. Той обаче стана твърде негъвкав, за да се справи със сложните изисквания от страна на клиента. В резултат на това зад сцената се случва повече извличане на данни и REST се представи зле с този растеж. За да се преодолее негъвкавостта и неефективността, беше създаден GraphQL.

В тази статия ще изградим приложение за ресторант, което проследява готвачи и ястия, които могат да бъдат запитвани и актуализирани с помощта на GraphQL

Какво е GraphQL?

GraphQL е език за заявки, създаден от Facebook с цел изграждане на надеждни клиентски приложения, базирани на интуитивен и гъвкав синтаксис. Той описва напълно изискванията за данни и взаимодействията със съществуваща база данни. GraphQL е разработен вътрешно от Facebook и пуснат през 2015 г.

GraphQL заявката е низ, който се изпраща до сървър, за да бъде интерпретиран и изпълнен, а отговорът връща JSON обратно на клиента.

Защо се нуждаем от GraphQL?

При традиционните извиквания на REST API нямахме възможност клиентът да поиска персонализиран набор от данни. За разлика от това, GraphQL позволява на клиентите да дефинират структурата на необходимите данни и същата структура на данните се връща от сървъра. Това предотвратява връщането на прекалено големи количества данни. Въпреки това, той също така добавя слой на сложност, който може да не е приложим за прости API.

Освен това поддържането на множество крайни точки е трудно в REST архитектурата. Когато приложението расте, броят на крайните точки ще се увеличи, което води до необходимостта клиентът да иска данни от различни крайни точки. API на GraphQL са по-организирани чрез предоставяне на структурирани типове и полета в схемата, докато се използва една крайна точка на API за заявка на данни.

Преминаване към кода

Да започнем да се развиваме. Първо ще създадем нова папка и ще инициализираме нашия package.json файл. След това добавете следните пакети с командата, посочена по-долу:

yarn init
yarn add express graphql express-graphql mongoose

Сега можем да преминем към създаване на нашия основен файл app.jsв основната ни директория и да изискваме graphqlHTTP от пакета Express GraphQL.

const express = require('express');
const graphqlHTTP = require('express-graphql');

const mongo = require('mongoose');
const app = express();
mongo.connect('mongodb://***yourusername***:***yourpassword***@ds053317.mlab.com:53317/gql-demo', {
    useNewUrlParser: true,
    useUnifiedTopology: true
})

mongo.connection.once('open', () => {
    console.log('connected to database');
})

app.use(‘/graphiql’, graphqlHTTP({ schema: require(‘./schema.js’), graphiql: true}));

app.listen(8080, () => {
    console.log('Server running succefully...')
})

Тук изискваме express и graphqlHTTP от нашите инсталирани пакети. Ние също направихме нашата връзка с нашата MongoDB база данни, използвайки mlab. Като зададем true на graphiql, можем да изпращаме и получаваме заявки от браузъра подобно на Insomnia или Postman. Можем също да го обслужваме локално и да го тестваме на http://localhost:8080/graphiql, за да използваме конзолата.

Следващата ни стъпка е изграждането на нашите модели на данни за съхраняване на елементи в нашата база данни. Ще създадем нова папка mongo-models и ще създадем два файлаchef.jsи dishes.jsкакто по-долу:

Сега ще направим папка и ще я наименуваме Schema.jsкъдето ще добавим типове към кода и ще дефинираме нашия GraphQL API:

const graphql = require('graphql');

const Dish = require('../mongo-models/dish');
const Chef = require('../mongo-models/chef');

const {
    GraphQLObjectType,
    GraphQLString,
    GraphQLBoolean,
    GraphQLSchema,
    GraphQLID,
    GraphQLFloat,
    GraphQLList,
    GraphQLNonNull
} = graphql;


const DishType = new GraphQLObjectType({
    name: 'Dish',
    fields: () => ({
        id: {
            type: GraphQLID
        },
        name: {
            type: GraphQLString
        },
        tasty: {
            type: GraphQLBoolean
        },
        country: {
            type: GraphQLString
        },
        chefs: {
            type: ChefType,
            resolve(parent, args) {
                return Chef.findById(parent.chefsId)
            }
        }
    })
});

const ChefType = new GraphQLObjectType({
    name: 'chefs',
    fields: () => ({
        id: {
            type: GraphQLID
        },
        name: {
            type: GraphQLString
        },
        rating: {
            type: GraphQLFloat
        },
        dish: {
            type: new GraphQLList(DishType),
            resolve(parent, args) {
                return Dish.find({
                    chefsId: parent.id
                })
            }
        }
    })
});

В горния код импортирахме graphql и нашите модели Mongo от нашата папка. Ние също дадохме дефиниции на типове на нашите типове данни в GraphQL, които са обвити във функция на поле с дебела стрелка. В GraphQL имаме функцията за разрешаване, която се задейства, когато пишем някои основни заявки, докато ще видим в следващите стъпки.

Във функцията resolve получаваме данни от базата данни.

const RootQuery = new GraphQLObjectType({
    name: 'RootQueryType',
    fields: {
        dish: {
            type: DishType,
            args: {
                id: {
                    type: GraphQLID
                }
            },
            resolve(parent, args) {
                return Dish.findById(args.id);
            }
        },
        chefs: {
            type: ChefType,
            args: {
                id: {
                    type: GraphQLID
                }
            },
            resolve(parent, args) {
                return Chef.findById(args.id);
            }
        },
        dishes: {
            type: new GraphQLList(DishType),
            resolve(parent, args) {
                return Dish.find({});
            }
        },
        chefs: {
            type: new GraphQLList(ChefType),
            resolve(parent, args) {
                return Chef.find({});
            }
        }
    }
});

const Mutation = new GraphQLObjectType({
    name: 'Mutation',
    fields: {
        addDish: {
            type: DishType,
            args: {
                name: {
                    type: new GraphQLNonNull(GraphQLString)
                },
                country: {
                    type: new GraphQLNonNull(GraphQLString)
                },
                tasty: {
                    type: new GraphQLNonNull(GraphQLBoolean)
                }
            },
            resolve(parent, args) {
                let dish = new Dish({
                    name: args.name,
                    country: args.country,
                    tasty: args.tasty,
                });
                return dish.save();
            }
        },
        addChef: {
            type: ChefType,
            args: {
                name: {
                    type: new GraphQLNonNull(GraphQLString)
                },
                rating: {
                    type: new GraphQLNonNull(GraphQLString)
                }
            },
            resolve(parent, args) {
                let chef = new Chef({
                    name: args.name,
                    rating: args.rating
                });
                return chef.save();
            }
        }
    }
})

module.exports = new GraphQLSchema({
    query: RootQuery,
    mutation: Mutation
});

Добавихме горния ред код във файла schema.js. Тук добавихме rootquery, за да получим типа ястие с id и също така да върнем всички списъци с ястия с импортиране GraphQLList. Същото важи и за chefs.

Също така добавихме Мутация към нашите обекти в GraphQL, където можем да добавим ястие към базата данни със задължителното поле GraphQLnonNull import. Във функцията за разрешаване ние върнахме новия обект и го запазихме в базата данни. Същото важи и за мутацията за готвачи.

И накрая, имаме експортите на нашия rootquery и mutationв крайна сметка.

Това е! Вече имаме работещAPI, използващ GraphQL с Node.

Също така свързах моята GitHub връзка тук, така че вие ​​да можете да разклоните и работите с наличния код — Връзка тук

Справочни показания:







*********************** — Приятно кодиране — ***********************