graphQL学习记录

蒋健
2023-12-01
1 什么是graphql
graphql 用官网的话来说就是一个api查询语言,但是通篇学习会发现graphql并没有自己的语言实现,而是通过在其他语言当中加入相对应的graphql库去实现graphql的定义标准。学习graphql的重心就是学习graphql的概念,实现细节就跟引入相应语言的graphql库有关,有些库可能就只是轻量级的实现并未完全实现,使用之前要查看相应库的说明。
2graphql带来的好处
所需数据完全定制,减少对服务器的请求。服务器端的代码完全跟视图解耦,后台只要维护相应的数据定义,和对数据库操作的实现。
3相关学习网站
http://graphql.cn/ 中文网站基础概念都有讲解,但是讲解的例子不连贯,难以联系上下文,不友好,不方便学习
https://graphql.org/ 外网英文好可以看
4重要的基础概念
一个 GraphQL schema 中的最基本的组件是对象类型,它就表示你可以从服务上获取到什么类型的对象,以及这个对象有什么字段。使用 GraphQL schema language,我们可以这样表示它:

type User{
name:String!
friends:[User]!
}
在schema中大部分的类型都是普通对象类型,但是有两个特殊类型:

schema{
query:Query,
mutation:Mutation
}
type Query{
hero:String
name:String
}
type Mutation{
sex:String
age:String
}
Query和Mutation可以改成其他任何名字如Query1、Query2、Mutation1、Mutation2等等,使用Query和Mutation作为名字只是一种约定,代表他们是所有query(查询)或者mutation(变更)的入口。
做了定义我们就可以这样查询
query {
hero
name
}
不带query关键字就是默认query查询与显式的使用query相同。


定义好了对象和入口之后就要定义执行函数,也就是resolver函数,每个字段都有对应的执行函数。
执行函数就是要返回与查询结构对应字段的数据,如果一个字段产生一个对象,则该查询将继续执行该对象对应字段的解析器,直到生成标量值。
使用js表示
Query: {
  //这就是一个查询resolver函数,对应Query下的hero字段,这个字段在上文中是个标量String所以查询到数据就会停止继续查询。
  hero(obj, args, context, info) {
    return context.db[args.id];
    )
  }
}
这个hero解析函数(resolver函数)的四个参数的意义
obj:上一级对象,如果字段属于根节点查询类型通常不会被使用。
args :可以提供在 GraphQL 查询中传入的参数。
context :会被提供给所有解析器,并且持有重要的上下文信息比如当前登入的用户或者数据库访问对象。
info: 一个保存与当前查询相关的字段特定信息以及 schema 详细信息的值。
知道以上概念就可以搭建一个简单的graphql服务器
5上手搭建graphql服务
需要安装的包
npm install graphql apollo-server-koa graph-tools koa koa-bodyparser koa-router --save
直接上代码
let Koa = require('koa');
let Static = require('koa-static');//这个可以不安装
let Router = require('koa-router');
let bodyParse = require('koa-bodyparser');
let { makeExecutableSchema } = require('graphql-tools');
let {graphiqlKoa,graphqlKoa} = require("apollo-server-koa");

// Some fake data
const books = [
    {
        id:1,
        title: "Harry Potter and the Sorcerer's stone",
        author: 'J.K. Rowling',
        user:{
            name:"koa",
            price:'12123$',
            id:1,
        }
    },
    {
        id:2,
        title: 'Jurassic Park',
        author: 'Michael Crichton',
        user:{
            name:"boa",
            price:'12333$',
            id:2,
        }
    },
    {
        id:3,
        title: 'Jurassic Park1',
        author: 'Michael Crichton2',
        user:{
            name:"sunshine-boy",
            price:'1232$',
            id:3,
        }
    },
    {
        id:4,
        title: 'Jurassic Park3',
        author: 'Michael Crichton4',
        user:{
            name:"beauty-girl",
            price:'123$',
            id:4,
        }
    },
];

// The GraphQL schema in string form
const typeDefs = `
  type Query { 
  books: [Book] 
  user(id:ID):User
  book:Book
  }
  type Book { 
    title: String, 
    author: String,
    id:ID,
  }
  type User{
    name:String,
    price:String,
    id:ID
  }
`;

// The resolvers
const resolvers = {
    Query: {
        books: (root,params,options) => {
            if(!params.id){
                return books;
            }else {
                return books[params.id];
            }
        } ,
        user:(root,params,options) => {
            if(params.id){
                return books[params.id-1].user;
            }
        } ,
    },
};

// Put together a schema
const schema = makeExecutableSchema({
    typeDefs,
    resolvers,
});

const app=new Koa();

const router = new Router();

router.get('/hello',function (ctx,next) {
    ctx.body="你好 世界!";
    next();
});

router.post('/graphql', graphqlKoa({ schema }));
router.get('/graphql', graphqlKoa({ schema }));

router.get(
    '/graphiql',
    graphiqlKoa({
        endpointURL: '/graphql', // a POST endpoint that GraphiQL will make the actual requests to
    }),
);

app.use(bodyParse());
app.use(Static(__dirname));
app.use(router.routes()).use(router.allowedMethods());

app.listen(8300);

process.stdin.on("data",function (data) {
    if(data.toString().trim()==="exit"){
        process.exit(0);
    }
});
完结

 类似资料: