• 日常分享graphql


    一、介绍

    image

    Graphql是一种面向数据的API查询语言


    Graphql给前端提供一种强力的查询工具,我们可以根据自己定义(需要)的格式去拿数据,它有自己的一套类型(schema)系统,schema 是 type、interface、enum 和 union 的集合,用来构建你的 API 数据模型; 类型系统在客户端和服务端之间提供了强类型的条约;我们想要什么,它就会准确给你返回什么,无冗余;

    二、优缺点和对比

    对比

    image
    image
    image

    优缺点对比

    1. API接口数量众多维护成本高:接口的数量多、颗粒度较粗;graphql单个查询即可返回需要的信息,服务端只需要对客户端暴露一个地址即可
    //如,要查A的表哥的公司的老总的父亲的车子是什么,可能需要多个api组合进行查询,而graphql一步到位;
    query {
      user (name : “A”) {
        cousin{
        	boss{
        		father{
        			car
        	        }
        		}
        	}
      }
    }
    // 一般REST API需要多个接口查询,面对当前业务,新增接口也是开发成本
    
    1. 接口扩展成本高, 需求更换时,涉及到多接口合并,前端会增加请求数,还需要做数据处理等;

    2. 传统API接口:后端更新接口字段,文档未及时更新,可能影响到前端;graphql直接面向数据,通过 GraphiQL 这个可视化调试界面展现服务端能提供的所有数据,开发过程不再依赖接口文档;

    3. 基于目前大多数企业架构,GraphQL应用需要前后端统一改造,适用方案较少,风险和成本较高;推动难度较大;比较试用全栈项目;GraphQL数据库查询性能存在瓶颈,服务端那边是需要平衡接口复杂度与数据库查询语言之间的复杂度;

    GraphQL 为何没有火起来?

    宋小菜GraphQLParty

    三、主要概念

    1. 模式schema

    定义了字段的类型、数据的结构,描述了接口数据请求的规则,当我们进行一些错误的查询的时候 GraphQL 引擎会负责告诉我们哪里有问题,和详细的错误信息,

    # src/schema.graphql
    
    # 接口定义
    interface UserInterface {
        id: ID!
        name: String!
        age: Int
        gender: Gender
    }
    
    interface BobbyInterface{
        hobby: String!
    }
    
    # 枚举定义 一般声明一组取值是常量的列表,字段属性需要大写
    enum Gender {
        MAN
        WOMAN
    }
    
    # 对象User的定义,type类似js的对象
    type UserInfo implements UserInterface { // 继承
        id: ID!
        name: String!
        age: Int!
        gender: Gender
    }
    
    type UserHobby implements BobbyInterface {
        id: ID!
        name: String!
        age: Int!
        gender: Gender
        hobby: String!
    }
    
    # 定义联合类型,进行字段的拓展
    
    union User = UserInfo | UserHobby
    
    
    # 定义Query入口
    type Query {
        user(id: String!): [User]
        // 标量类型:GraphQL 中内置有一些标量类型 String、Int、Float、Boolean、ID(ID类型代表着一个独一无二的标识、类似主键),用户也可以定义自己的标量类型
        // !符号表示该字段不可空
        // []: List类型、表示某个字段返回不止一个标量类型的数据
    }
    
    # 实现query查询
    
    query{
        user(name: "范德彪") {
            id
            name
            age
            gender
        }
    }
    
    # Mutation定义,实现RUD
    type Mutation {
        createUser(id: ID!, name: String!, email: String!, age: Int,gender: Gender): User!
        updateUser(id: ID!, name: String, email: String, age: Int, gender: Gender): User!
        deleteUser(id: ID!): User
    }
    
    

    解析函数 Resolver: 负责到数据库中取得数据并返回

    Query {
      articles {
      	 id
      	 author {
      	 	name
      	 }
      	 comments {
          id
          desc
          author
        }
      }
    }
    
    
    • 第一层解析,使用articles的Resolver获取解析数据,

    • 第二层解析

    1. id在Author类型中为标量类型,解析结束
    2. author在Author类型中为对象类型User,尝试使用User的Resolver获取数据,当前field解析完毕
    3. 之后对第二层解析的返回值,进行第三层解析,当前author还包含一个Query, name,直到它是标量类型,解析结束

    四、应用

    1. React + Graphql

    Apollo

    Apollo 是基于 GraphQL 的全栈解决方案集合;包括了 apollo-client 和 apollo-server 。

    下面用到一个apollo提供的工具apollo-server-koa,实现一个demo

    • 创建koa2项目、使用 apollo-server-koa起一个graphql服务
      image

    • 创建react+graphql

    // 快速创建react demo
    $ npx create-react-app graph-react
    $ cd graph-react
    $ npm start
    
    • 修改index.js
      image

    • 添加graphql.js / 初始化获取graph服务端数据
      image

    • 修改App.js
      image

    • 返回结果
      image

    1. 配送服务graphql相关

    hasura引擎和数据的CRUD

    // 查询数据
    {
      delivery_config(where: {id: {_eq: "lmXVOrQ8RMKezj89yP9aqw3xpo1JNL"}}) {
        id
        type
        delivery_config_extras {
          id
          value
          key
        }
      }
    }
    
    

    image

    // 更新数据
    mutation {
      update_delivery_config(where: {id: {_eq: "lmXVOrQ8RMKezj89yP9aqw3xpo1JNL"}}, _set: {foreign_type: 2}) {
        affected_rows
      }
    }
    
    
    // 插入数据
    mutation {
      insert_delivery_config(objects: {brand_id: "100011", foreign_type: 1, delivery_config_extras: {data: {key: "testkey", value: "test", id: 123453323, created: "1574927283661", modified: "1574927283663"}}, id: "111233", created: "1574927283666", modified: "1574927283633", type: 2}) {
        returning {
          brand_id
        }
      }
    }
    
    
    // 删除数据
    // 先删除关联数据
    mutation {
      delete_delivery_config_extra(where: {id: {_eq: 123453323}}) {
        affected_rows
      }
    }
    
    mutation {
      delete_delivery_config(where: {id: {_eq: "111233"}}) {
        affected_rows
      }
    }
    
    

    五、总结

    Graphql带来新的开发思路,前后端职责会随之调整,不过实际应用前可能需要协调成本,尤其是对很多成熟项目,当前的一套后端稳定运行,如果推送更换graphql,可能会遇到很多调整和挑战,并且成熟方案并没有那么多,目前更适合小的全栈类型的项目等;

    参考链接:

    koa2+graphql server demo

    koa2+graphql+react demo

    github V4 graphql

    graphql文档

    apollo文档

  • 相关阅读:
    10大开源文档管理系统,知识管理系统
    okhttp原理,okhttp为什么好?
    开放式创新对程序开发有什么深远的影响?
    TypeScript中文手册【从入门到精通】
    CentoOS6 32停更了,如何继续用yum源【解决方案】
    electronic为什么要用JavaScript开发桌面应用
    统一身份认证登录入口,统一用户认证和单点登录解决方案
    PHP数组如何倒叙 array_reverse
    Windows electron开发实例大全
    AI深度学习的基础上处理自然语言
  • 原文地址:https://www.cnblogs.com/mapleChain/p/14967393.html
Copyright © 2020-2023  润新知