Installation steps:
1.npm install
2. Install and connect the database
Conf /db.js /graphql.sql
3. Startup procedure
npm start
4. Visit:
localhost:3003
View related interface access through developer tools
5. Access the debugging tool:
http://localhost:3003/graphql
http://localhost:3003/article
6. The official simple version
/app_simple.js
7. Minimum implementation version of Schame
/graphql/user/userSchame.js
What is GraphQL
GraphQL is an application-level query language developed by Facebook in 2012 and open source in 2015. You define a graphQL-based pattern in the background, and then your clients can query the data they want, without having to redefine an interface to return the data you need.
Because you don’t need to change your background, this approach is better than the REST API approach and gives you the flexibility to change the data display on different clients.
GraphQL is a specification. This means you can implement GraphQL in any language. Click here to see more about GraphQL. Facebook has a GraphQL implementation for JavaScript.
Why use it
GraphQL provides an easy-to-understand set of complete descriptions of the data in your API, enabling a client to get exactly what it needs without any redundancy, making it easier for the API to evolve over time, and for building powerful developer tools. Get multiple resources with one request
-
Declarative. The format of the results describing all possible types of system queries is determined by the requester (that is, the client) rather than the responder (that is, the server). You don’t need to write a lot of extra interfaces to accommodate client requests
-
Reduce the maintenance workload of development documents, and correspondingly reduce communication costs
-
Strongly typed. Each GraphQL query must follow its set type to be executed.
-
Requests to merge multiple interfaces can be combined into one
-
Ask for the data you want no more, no less
How to use
introspection
GraphQL is introspective, which means you can query a GraphQL to know its own schema details.
Query __schema to list all types defined in that schema and get the details for each:
query {
__schema {
types {
name
kind
description
fields {
name
}
}
}
}
Copy the code
Query __type for details of any type:
query {
__type(name: "Repository") {
name
kind
description
fields {
name
}
}
}
Copy the code
Tip: Introspection queries are probably your only GET requests in GraphQL. Whether it's query or mutation, the GraphQL request should be POST if you want to pass the request body
The query
List query (no parameters)
{
courses {
id
score
course
}
}
Copy the code
Results:
{" data ": {" courses" : [{" id ": 1," score ": 33," course ":" mathematics "}, {" id ": 2," score ": 55," course ":" the language "}, {" id ": 3, "score": 55, "course": "math"}]}Copy the code
### separate query (with parameters)
{
course(id:1) {
score
course
}
}
Copy the code
Results:
{" data ": {" course" : {" score ": 33," course ":" mathematics "}}}Copy the code
change
mutation {
addUser (name:"nk",sex:"22",intro:"sdfasdfasdf"){
id
}
}
Copy the code
Results:
{
"data": {
"addUser": {
"id": 26
}
}
}Copy the code
Combination query
{
courses {
id
score
course
}
users {
id
name
}
}
Copy the code
The results of
{" data ": {" courses" : [{" id ": 1," score ": 33," course ":" mathematics "}, {" id ": 2," score ": 55," course ":" the language "}], "users" : [ { "id": 1, "name": "xiaoming" }, { "id": 2, "name": "2" }, { "id": 3, "name": "2333" } ] } }Copy the code
Query the alias
Sometimes we want to look like this to separate the data so that we can call it in different places:
{
postsnoargs{
title
},
postsnoargs{
_id
}
}Copy the code
Here’s what we’re imagining:
{
"data": {
"postsnoargs": {
"title":[
"title": "Sharing the Meteor Login State Between Subdomains",
],
"_id":[
"_id": "0176413761b289e6d64c2c14a758c1c7"
]
}
}
}Copy the code
But the server actually returns something like this:
{
"data": {
"postsnoargs": [
{
"title": "Sharing the Meteor Login State Between Subdomains",
"_id": "0176413761b289e6d64c2c14a758c1c7"
}
]
}
}Copy the code
We need to set the alias, otherwise the server will return to merge your data:
{
posttitle:postsnoargs{
title
},
postid:postsnoargs{
_id
}
}Copy the code
The server returns:
{
"data": {
"posttitle": [
{
"title": "Sharing the Meteor Login State Between Subdomains"
}
],
"postid": [
{
"_id": "0176413761b289e6d64c2c14a758c1c7"
}
]
}
}Copy the code
query {
corsesssssss:courses {
id
score
course
}
users {
id
}
}Copy the code
Query the user input type
mutation {
addUserByInput (userInfo:{
name:"222222",
intro:"33",
sex:"2"
}) {
id
}
}
Copy the code
Results:
{
"data": {
"addUserByInput": {
"id": 27
}
}
}Copy the code
How to pass arguments to call the GraphQL API
// (unit:cm)
{
user(id: 0) {
name
stature(unit: MM)
intro
id
}
}Copy the code
Nested query
http://localhost:3003/article
Sometimes we need to filter the queried data, such as limiting the size, and we need a nested query to do this.
For example, the following query starts with A national province information:
{
address(nameKey:"A"){
ShortKey,
Content(limit:5) {
Id,
Code,
Name,
FirstStr
}
}
}Copy the code
The server returns:
{" data ": {" address" : [{" ShortKey ":" A ", "Content" : [{" Id ": 36," Code ":" 152900 ", "Name" : "la shan union", "FirstStr" : "A"}, {" Id ": 39," Code ":" 210300 ", "Name" : "anshan city", "FirstStr" : "A"}, {" Id ": 105," Code ":" 340800 ", "Name" : "Anqing city," "FirstStr" : "A"}, {" Id ": 155," Code ":" 410500 ", "Name" : "anyang city", "FirstStr" : "A"}, {" Id ": 293," Code ": "513200", "Name" : "aba Tibetan and qiang autonomous prefecture," "FirstStr" : "A"}}}}]]Copy the code
The Content field limits the return of the top five markets. Note that the limit is set by the server, not the Graphql keyword.
Back-end parse queries
graphql(schema, ' query HeroNameAndFriends{\n' +
'\tcourses {\n' +
' id\n' +
'\t score\n' +
'\t course\n' +
'\t}\n' +
'}', root).then((response) => {
console.log(response);
});
Copy the code
shard
http://localhost:3003/article
In GraphQL, a fragment is a fragment that can be reused.
If we need to query information about three different articles, we might do the following query:
{
first:posts(index:1){
title,
category,
layout
},
second:posts(index:2){
title,
category,
layout
},
third:posts(index:3){
title,
category,
layout
}
}Copy the code
We ran the above posts query over and over again, and it might not seem like much at first, but when the data you need to query has dozens of fields, you start to get a headache (trust me).
So what are some ways that we can reuse this piece that we use a lot?
Let me give you the answer:
fragment post on Post{
title,
category,
layout
}Copy the code
The above is a shard,Post is a server defined type, you can look at the document in the upper right corner, each operation name will have a return type.
Let’s start with this shard:
{ first:posts(index:1){ ... post }, second:posts(index:2){ ... post }, third:posts(index:3){ ... post } } fragment post on Post{ title, category, layout }Copy the code
Using object expander… If you’re familiar with ES6, you’ll be particularly familiar with this, so could we try something similar in ES6?
Let’s try:
{ first:posts(index:1){ ... post }, second:posts(index:2){ ... post, category }, third:posts(index:3){ ... post, layout } } fragment post on Post{ title, category, }Copy the code
It doesn’t seem to be a problem at all, the server is returning the correct information, I won’t explain this, it is all ES6 stuff, if you don’t understand ES6 then you should hurry up.
Shard summary
Shards can also be nested, so you can write shards for any data type defined by the server, which greatly reduces the time you spend writing duplicate code.
Query variable
As mentioned above, sharding can save a lot of time, so now I’m going to talk about query variables that can increase your life (ok, I admit I’m pulling my hair out).
For the query with parameters above, we queried the data when index equals 1,2, and 3. Sharding reduces the time you need to enter the same field, and query variables reduce the time you need to write the shard…
How much nonsense fill, first look at the code:
query getFewPosts($index: Int!) { first:posts(index:$index){ ... post } } fragment post on Post{ title, category, }Copy the code
Then enter in the query window:
{
"index":1
}Copy the code
This is a simple variable query that can also be used with sharding. You can add several variables to increase the use of sharding:
query getFewPosts($index: Int! , $index1: Int! , $index2: Int!) { first:posts(index:$index){ ... post }, second:posts(index:$index1){ ... post, category }, third:posts(index:$index2){ ... post, layout } } fragment post on Post{ title, category, }Copy the code
Then enter in the query window:
{
"index": 1,
"index1": 2,
"index2": 3
}Copy the code
Front-end query:
var xhr = new XMLHttpRequest(); xhr.responseType = 'json'; xhr.open("POST", "/article"); xhr.setRequestHeader("Content-Type", "application/json"); xhr.setRequestHeader("Accept", "application/json"); xhr.onload = function () { console.log('data returned:', xhr.response); } xhr.send(JSON.stringify({ query: ` query getFewPosts($index: Int! , $index1: Int! , $index2: Int!) { first:posts(index:$index){ ... post }, second:posts(index:$index1){ ... post, category }, third:posts(index:$index2){ ... post, layout } } fragment post on Post{ title, category, } `, variables:{ "index": 1, "index1": 2, "index2": 3 } }));Copy the code
How is the server implemented
Simple way (app_simple.js)
var express = require('express'); var graphqlHTTP = require('express-graphql'); var { GraphQLList, GraphQLObjectType, GraphQLSchema, GraphQLString, GraphQLInt, GraphQLFloat, GraphQLEnumType, GraphQLNonNull, GraphQLInterfaceType, GraphQLInputObjectType, GraphQLUnionType } = require('graphql'); Var animals=[{chinaName: 'dog ', legs: 4}, {englishName: 'fish', tailColor:'red'},]; // define schema and resolver const Dog = new GraphQLObjectType({name: 'Dog', description: 'Dog entity ', fields: () => ({chinaName: {type: new GraphQLNonNull(GraphQLString)}, legs: {type: new GraphQLNonNull(GraphQLInt)}, }), isTypeOf:obj=>obj.legs, }); Const Fish=new GraphQLObjectType({name:'Fish', description:" Fish entity ", fields: () => {return ({englishName: {type: new GraphQLNonNull(GraphQLString)}, tailColor: {type: new GraphQLNonNull(GraphQLString)}, }); }, isTypeOf:obj=>obj.tailColor, }); const Animal = new GraphQLUnionType({ name: 'Animal', description: 'Union', types:[Dog,Fish], resolveType:function (obj) { if(obj.legs) { return Dog; }else if(obj.tailColor){ return Fish; }else{ return null; }}}); Const Query=new GraphQLObjectType({name:'AnimalQuery', description:' AnimalQuery', Fields ()=>({animals:{type:new GraphQLList(Animal), description:' Query all animals ', resolve:function () {return animals; }}})}); const schema = new GraphQLSchema({ types: [Dog, Fish,Animal], query: Query }); var app = express(); App. use('/graphql', graphqlHTTP({schema: schema, graphiQL: true, // enable graphiQL})); App.listen (4000, () => console.log(' localhost:4000/graphql'));
Copy the code
The GraphQL has the corresponding JavaScript type:
GraphQLObjectType,// custom type GraphQLSchema,// Define view GraphQLInterfaceType,// describe multiple types of generic field GraphQLList,// other types of encapsulation GraphQLString,// String type GraphQLInt,// integer float,// float type GraphQLEnumType,// iterable type GraphQLNonNull,// null-not allowed, accepts a GraphQL typeCopy the code
Define a query
Const Post = new GraphQLObjectType({name:"Post", description:" an article ", Fields ()=>({_id:{type:new GraphQLNonNull(GraphQLString),// null is not allowed}, Title :{type:new GraphQLNonNull(GraphQLString),// can't be empty}, category:{type:GraphQLString}, layout:{ type:GraphQLString }, content:{ type:GraphQLString }, }) });Copy the code
An article contains the id, title, category, layout, and the content of these information, the empty string is not allowed in the id and title, if the query to the data without the two would be an error.
Once defined, we need to create a reference in the root query, otherwise the definition will not be used:
Const Query = new GraphQLObjectType({name: 'BlogSchema', description: 'Root of the Blog Schema', fields: () => ({// echo: {//... }, // Post query posts:{type:new GraphQLList(Post), args:{index:{type:GraphQLInt}}, Resolve :(source,args)=>{return [PostsList[args.index]],// return array (although only one)}}}); })Copy the code
The article query posts receives an index parameter, which is an integer.
Resolve returns the corresponding article information stored in the PostsList array, because posts returns an array (all the data in the array is Post objects), and the query is a Post object, so it needs to be enclosed in an array number.
Sometimes you need to nest severalGraphQLObjectType
For example, schema.js in the project defines an address query and three layers of query.
Mutation
Sometimes when the client queries the data, it is also accompanied by modifying the data and creating the data, so here we also introduce how to update the data.
Let’s look at a Mutation operation:
Mutation CREATE{createAddress(Id:1,Code:"13156", FirstStr:"S"){Id, Name, Code,}}Copy the code
Add a prefecture level city with the following fields :Id,Code,Name,FirstStr.
CREATE is a mutation name, not a keyword, so you can use any other name you like.
CreateAddress is a keyword defined by the server that accepts four fields, with the created information returned in curly braces.
Let’s look at the server side:
Const Mutation = new GraphQLObjectType({name:"Mutation", description:" add/delete data ", fields:()=>({ createAddress:{ type:AddressContent, args:{ Id:{ type:new GraphQLNonNull(GraphQLInt) }, Code:{ type:new GraphQLNonNull(GraphQLString) }, Name:{ type:new GraphQLNonNull(GraphQLString) }, FirstStr:{ type:new GraphQLNonNull(GraphQLString) } }, resolve:(source,args)=>{ let address = Object.assign({},args); / / get the data / / to uppercase address. FirstStr = address. FirstStr. The toUpperCase (); let queryData = _.find(AddressList,item=>item.ShortKey===address.FirstStr); If (queryData){// If (queryData){// If (queryData.content.push (address); // console.log(address) return address; } else{return null; }}}})})Copy the code
todoList
-
Learn to use DataLoader to get list data
-
Advanced usage interface federation, etc
# Related documents:
Official Video Tutorial
GraphQL series is a quick start tutorial
GraphQL series two data types
GraphQL series 3 JavaScript basics
This series is better
What the devil GraphQL
GraphQL exploration of node.js server practice
GraphQL with Koa Best Introductory practices
Basic set of implementation, but no database, can not run through
GraphQL: From REST to GraphQL, a more complete data query definition
GraphQL: An interface style that differs from REST
Github: github.com/zhaiqianfen… Github.com/proYang/Gra… The KOA implementation documentation is good and the package is good. Pretty good ### pit
The node support import
Create a new start.js file in your project folder and write the following code inside:
require('babel-core/register')({
'presets': [
'stage-3',
["latest-node", { "target": "current" }]
]
})
require('babel-polyfill')
require('./server')
Copy the code
Then, from the command line, run NPM install babel-core babel-polyfill babel-preset-latest-node babel-preset-stage-3 –save-dev to install a few development modules.
Once installed, run Node start.js from the command line
mysql
1. Async awit problem between graphQL and mysql database query