Zde je živá verze Glitch. (před změnou udělejte remix)
Frontend část
Obsah
- Obsah
- Co je graphql?
- Úvod
- Předpoklady instalace
- Typy GraphQL
- TodoType
- RootQueryType
- Typ mutace
- Kód lepení
- Spuštění serveru Express GraphQL
- Testovací dotazy a mutace
- Závěr
Co je graphql?
Dotazovací jazyk používaný k definování API, který poskytuje úplný a srozumitelný popis dat a umožňuje výkonné vývojářské nástroje.
Více na Graphql.
Úvod
Toto je backendová část základní TodoApp využívající ExpressJS a GraphQL.
Náš Backend bude používat express-graphql v kombinaci s mongoose a pro server budeme používat ExpressJS.
Pro přístup k živé verzi na Glitch.
Předpoklady instalace
Přejděte do adresáře projektů a zkopírujte a vložte následující příkazy:
mkdir todo-express-graphql && cd todo-express-graphql
npm install cors express express-graphql graphql mongoose
Typy GraphQL
cd todo-express-graphql && mkdir schema && cd schema && touch todo_type.js
TodoType
const mongoose = require('mongoose');
const graphql = require('graphql'); //package used to build our graphql schema
const {
GraphQLObjectType,
GraphQLID,
GraphQLInt,
GraphQLString
} = graphql; //necessary types for defining our schema
const TodoType = new GraphQLObjectType({
name: 'TodoType',
fields: () => ({
id: { type: GraphQLID },
likes: { type: GraphQLInt },
content: { type: GraphQLString },
})
});
module.exports = TodoType;
Když definujeme typ pro naše schéma GraphQL, musíme vytvořit instanci GraphQLObjectType
a předejte objekt s povinnými poli pro náš typ.
name
je jediné povinné pole na GraphQLObjectType
.
Některé z nejčastěji používaných vlastností, které pokryjeme později v tomto příspěvku, jsou fields
, potřebné k definování atributů, které tento typ řeší, a resolve
funkce.
Podívejte se prosím na oficiální dokumentaci graphql týkající se GraphQLObjectType
RootQueryType
const mongoose = require('mongoose');
const graphql = require('graphql');
const {
GraphQLObjectType,
GraphQLList,
GraphQLID,
GraphQLNonNull
} = graphql;
const Todo = mongoose.model('todo');
const TodoType = require('./todo_type');
const RootQueryType = new GraphQLObjectType({
name: 'RootQueryType',
fields: () => ({
todos: {
type: new GraphQLList(TodoType),
resolve() {
return Todo.find({});
}
},
todo: {
type: TodoType,
args: { id: { type: new GraphQLNonNull(GraphQLID) } },
resolve(parentValue, { id }) {
return Todo.findById(id);
}
}
})
});
module.exports = RootQueryType;
RootQueryType
má všechny kořenové koncové body potřebné ke spotřebě našeho zdroje úkolů. Zde definujeme todos
koncový bod jako odpověď, která bude obsahovat seznam TodoType
dokumenty pomocí GraphQLList(TodoType)
. Další je naše todo
koncový bod používaný pro načítání a
jeden úkol z naší databáze.
GraphQLNonNull
se používá, protože se potřebujeme ujistit, že naše id
přijatý jako parametr dotazu není nedefinovaný.
resolve(parentValue, { id })
první argument, který funkce resolve obdrží, je parentValue nebo root, což je hodnota předaná z jiných typů. Tento argument umožňuje vnořenou povahu dotazů GraphQL.
Druhým argumentem je objekt se skutečnými parametry dotazu.
Na express-graphql je hezké, že vždy očekává, že bude vrácen slib z funkce resolveru a použití mongoose se integruje
opravdu hladce.
Více o resolverech z dokumentace ApolloGraphQL.
MutationType
Mutace se obvykle používají ke změně dat z naší databáze a můžete vidět, že jsou velmi podobné našemu RootQueryType
, kromě toho, že nyní měníme data na základě parametrů dotazu.
const graphql = require('graphql');
const { GraphQLObjectType, GraphQLString, GraphQLID } = graphql;
const mongoose = require('mongoose');
const Todo = mongoose.model('todo');
const TodoType = require('./todo_type');
const mutation = new GraphQLObjectType({
name: 'MutationType',
fields: {
addTodo: {
type: TodoType,
args: {
content: { type: GraphQLString }
},
resolve(parentValue, { content }) {
return (new Todo({ content })).save()
}
},
likeTodo: {
type: TodoType,
args: { id: { type: GraphQLID } },
resolve(parentValue, { id }) {
return Todo.like(id);
}
},
deleteTodo: {
type: TodoType,
args: { id: { type: GraphQLID } },
resolve(parentValue, { id }) {
return Todo.remove({ _id: id });
}
},
updateTodo: {
type: TodoType,
args: { id: { type: GraphQLID }, content: { type: GraphQLString } },
resolve(parentValue, { id, content }) {
return Todo.update({ _id: id }, { content });
}
},
}
});
module.exports = mutation;
Kód lepení
const graphql = require('graphql');
const { GraphQLSchema } = graphql;
const query = require('./root_query_type');
const mutation = require('./mutations');
module.exports = new GraphQLSchema({
query,
mutation
});
Ve většině případů, kdy budete psát soubory schématu, budete muset předat objekt se dvěma klíči:query
a mutation
. Docela jednoduché a přímočaré, stačí importovat potřebné mutace a dotazy
a předat je jako objekt GraphQLSchema
.
Více o GraphQLSchema
Spuštění serveru Express GraphQL
const express = require('express');
const expressGraphQL = require('express-graphql');
const mongoose = require('mongoose');
const todoModel = require('./models/todo');
const bodyParser = require('body-parser');
const schema = require('./schema');
const cors = require('cors')
const app = express();
app.use(cors());
const MONGO_URI = 'your mLab link';
if (!MONGO_URI) {
throw new Error('You must provide a MongoLab URI');
}
mongoose.Promise = global.Promise;
mongoose.connect(MONGO_URI);
mongoose.connection
.once('open', () => console.log('Connected to MongoLab instance.'))
.on('error', error => console.log('Error connecting to MongoLab:', error));
app.use(bodyParser.json());
app.use('/graphql', expressGraphQL({
schema, //pass the schema to our middleware
graphiql: true //enable graphiql interface so we can test our queries and mutations before starting to use it.
}));
app.get('/', (req, res) => {
res.redirect('/graphql');
});
app.listen(4000, () => {
console.log('Listening at 4000');
});
Testovací dotazy a mutace
Když musíte vytvořit dotaz a nevíte, jak přesně ho napsat
pak graphiql
pomůže https://apollo-graphql-todo.glitch.me/graphql.
Jednou ze schopností GraphQL je okamžitá dokumentace. Poté, co jsme definovali typy, které se budou používat v našem GraphQLSchema
máme připravenou dokumentaci. Stačí přejít na https://apollo-graphql-todo.glitch.me/graphql a vpravo nahoře najdete Docs
.
Psaní dotazů v graphiql:
query{
todos{
id
likes
content
}
}
Tento dotaz bude spuštěn na našem RootQueryType
a todos
pole bude převedeno na seznam TodoTypes
. TodoType
obsahuje
id
, likes
, content
jako vlastnosti a protože máme seznam, dostaneme zpět odpověď, která vypadá takto:
{
"data": {
"todos": [
{
"id": "5c5c21184c9edc006857c11b",
"likes": 17,
"content": ""
},
{
"id": "5c5c26e84c9edc006857c124",
"likes": 4,
"content": "asd"
},
{
"id": "5c5c29b296f75b0068f3b9db",
"likes": 0,
"content": "asdad"
},
{
"id": "5c5c29c296f75b0068f3b9dc",
"likes": 0,
"content": "eq123"
}
]
}
}
Jako cvičení zkuste upravit Přidat, Upravit a Smazat úkol.
Závěr
Express-graphql je skvělý nástroj pro vývoj backendů, které potřebují podporovat GraphQL, a nyní jsme viděli, jak snadno jej lze integrovat s MongoDB. Nyní máme malý příklad toho, jak byste mohli implementovat některé základní dotazy a mutace.
Doufám, že se vám tento článek líbil.