GraphQL学习笔记

一、GraphQL入门

什么是GraphQL?

GraphQL 是一个用于 API 的查询语言,是一个使用基于类型系统来执行查询的服务端运行时(类型系统由你的数据定义)。GraphQL 并没有和任何特定数据库或者存储引擎绑定,而是依靠你现有的代码和数据支撑。

一个 GraphQL 服务是通过定义类型和类型上的字段来创建的,然后给每个类型上的每个字段提供解析函数。例如,一个 GraphQL 服务告诉我们当前登录用户是 me,这个用户的名称可能像这样:

type Query {
  me: User
}
 
type User {
  id: ID
  name: String
}

一并的还有每个类型上字段的解析函数:

function Query_me(request) {
  return request.auth.user;
}
 
function User_name(user) {
  return user.getName();
}

一旦一个 GraphQL 服务运行起来(通常在 web 服务的一个 URL 上),它就能接收 GraphQL 查询,并验证和执行。接收到的查询首先会被检查确保它只引用了已定义的类型和字段,然后运行指定的解析函数来生成结果。

二、详细学习

1、基本参数类型

基本类型:String、Int、Float、Boolean和ID,可以在schema声明的时候直接使用

[类型]代表数组,例如:[Int]代表整型数组

和js传递参数一样,小括号内定义形参,但是注意:参数需要定义类型

!(叹号)代表参数不能为空(必须传递)

//numDice参数不能为空
type Query {
    rollDice(numDice:Int!, numSides:Int):[Int]
}

2、自定义参数类型

GraphQL允许用户自定义参数类型,通常用来描述要获取的资源属性

type Account {
    name:String
    age:Int
    sex:String
}
type Query {
    account(name:String):Account
}

3、在客户端访问graphql的接口

代码如下:

js代码:

const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');

//定义schema 查询和类型
const schema = buildSchema(`
  type Query {
    getClassMates(classNo: Int!): [String]
    account(username: String)
  }
`);

//定义查询对应的处理器
const root = {
  getClassMates: ({classNo}) => {
    const obj = {
      2: ['赵六', '田七', '周八']
    };
    return obj[classNo];
  }
};

//创建express应用
const app = express();


//使用express-graphql中间件处理GraphQL请求
app.use('/graphql1', graphqlHTTP({
  schema: schema,
  rootValue: root, 
  graphiql: true, //是否开启GraphiQL界面
}));


//公开文件夹,供用户访问静态资源
app.use(express.static('public'));
//启动express应用
app.listen(4000);

html代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button onclick="getData()"></button>
</body>
<script>
    function getData() {
        const query = `
        query Account($username: String){
            account(username: $username)
        }
        `


        const variables = {username:" "}
        fetch('/graphql', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                query: query,
                variables: variables,
            }),
        }).then(res => res.json)
           .then(json => {
                console.log(data); 
           }) 
    }
</script>
</html>

4、使用Mutations修改数据

查询使用query,修改数据使用Mutations

input AccountInput {
  username: String!
  age: Int!
  sex: String
  salary: Float
}

type Mutation {
    createAccount(input: AccountInput!): Account
    updateAccount(input: AccountInput!): Account
}

5、认证与中间件

代码如下:


const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');
//定义GraphQL Schema查询类型 mutations
const schema = buildSchema(`
    input AccountInput {
        name: String
        age: Int
        sex: String
        department: String
    }
    type Account {
        name: String
        age: Int
        sex: String
        department: String
    }
    type mutation {
        createAccount(input: AccountInput!): Account
        updateAccount(id: ID!, input: AccountInput!): Account
    }
    //必须得有query类型,否则会报错

    type query {
        accounts: [Account]
    }
`);

//模拟数据库功能
const fakeDB = {};

//定义查询对于的处理器
const root = {
    accounts(){
        return fakeDB;
    },
    createAccount: ({ input }) {
        //模拟数据库保存
        fakeDB[input.name] = input; 
        //返回保存的结果
        return fakeDB[input.name];
    },
    updateAccount: ({ id, input }) => {
        //模拟数据库更新
        const updateAccount = Object.assign({}, fakeDB[id], input);
        fakeDB[id] = this.updateAccount;
        //返回更新的结果
        return updateAccount;
    } 
};

const app = express();

//中间件处理GraphQL请求
const middleware = (req, res, next) =>{
    if(req.url.indexOf('/graphql') && req.headers.cookie.indexOf('auth') === -1){
        res.send(JSON.stringify({
            error:"您没有权限访问这个接口"
        }))
        return ;
    }
    next();
};
app.use(middleware)



app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true,
}));

app.listen(4000);

6、Constructing Types

使用Graphql ObjectType定义type(类型) 

使用Graphql ObjectType定义query(查询)

代码量会上升,但是可维护性会提高

三、具体实例

1、Hello World实例

准备工作:

安装依赖:

npm init -y

npm install graphql express express-graphql -S

//运行项目
node helloworld.js

代码如下:

const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');
//定义GraphQL Schema查询类型
const schema = buildSchema(`
  type Query {
    hello: String
  }
`);

//定义查询对于的处理器
const root = {
  hello: () => {
    return 'Hello world!';
  },
};

const app = express();

app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true,
}));

app.listen(4000);

运行效果如下:

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值