GraphQL 思想是以数据为中心的,定义 Schema 自然成为了开发的核心。定义 Schema 即是定义数据模型,需要根据业务制定,客户端和服务端共同维护。
Schema 中大部分的类型都是普通对象类型,但是一个 schema 内有两个特殊类型。
每一个 GraphQL 服务都有一个 query
类型,可能有一个 mutation
类型。这两个类型和常规对象类型无差,但是它们之所以特殊,是因为它们定义了每一个 GraphQL 查询的入口。
{
"data": {
"getAllDepts": [
{
"deptno": "10",
"dname": "ACCOUNTING",
"loc": "NEW YORK"
},
{
"deptno": "20",
"dname": "RESEARCH",
"loc": "DALLAS"
},
{
"deptno": "30",
"dname": "SALES",
"loc": "CHICAGO"
},
{
"deptno": "40",
"dname": "OPERATIONS",
"loc": "BOSTON"
}
],
"getAllEmps": [
{
"empno": "7369",
"ename": "SMITH",
"job": "CLERK",
"mgr": "7902",
"hiredate": "17-12-1980",
"sal": 800,
"comm": "",
"deptno": "20"
},
{
"empno": "7499",
"ename": "ALLEN",
"job": "SALESMAN",
"mgr": "7698",
"hiredate": "20-2-1981",
"sal": 1600,
"comm": "300",
"deptno": "30"
},
{
"empno": "7521",
"ename": "WARD",
"job": "SALESMAN",
"mgr": "7698",
"hiredate": "22-2-1981",
"sal": 1250,
"comm": "500",
"deptno": "30"
},
{
"empno": "7566",
"ename": "JONES",
"job": "MANAGER",
"mgr": "7839",
"hiredate": "2-4-1981",
"sal": 2975,
"comm": "",
"deptno": "20"
},
{
"empno": "7654",
"ename": "MARTIN",
"job": "SALESMAN",
"mgr": "7698",
"hiredate": "28-9-1981",
"sal": 1250,
"comm": "1400",
"deptno": "30"
},
{
"empno": "7698",
"ename": "BLAKE",
"job": "MANAGER",
"mgr": "7839",
"hiredate": "1-5-1981",
"sal": 2850,
"comm": "",
"deptno": "30"
},
{
"empno": "7782",
"ename": "CLARK",
"job": "MANAGER",
"mgr": "7839",
"hiredate": "9-6-1981",
"sal": 2450,
"comm": "",
"deptno": "10"
},
{
"empno": "7788",
"ename": "SCOTT",
"job": "ANALYST",
"mgr": "7566",
"hiredate": "13-7-87",
"sal": 3000,
"comm": "",
"deptno": "20"
},
{
"empno": "7839",
"ename": "KING",
"job": "PRESIDENT",
"mgr": "",
"hiredate": "17-11-1981",
"sal": 5000,
"comm": "",
"deptno": "10"
},
{
"empno": "7844",
"ename": "TURNER",
"job": "SALESMAN",
"mgr": "7698",
"hiredate": "8-9-1981",
"sal": 1500,
"comm": "0",
"deptno": "30"
},
{
"empno": "7876",
"ename": "ADAMS",
"job": "CLERK",
"mgr": "7788",
"hiredate": "13-7-87",
"sal": 1100,
"comm": "",
"deptno": "20"
},
{
"empno": "7900",
"ename": "JAMES",
"job": "CLERK",
"mgr": "7698",
"hiredate": "3-12-1981",
"sal": 950,
"comm": "",
"deptno": "30"
},
{
"empno": "7902",
"ename": "FORD",
"job": "ANALYST",
"mgr": "7566",
"hiredate": "3-12-1981",
"sal": 3000,
"comm": "",
"deptno": "20"
},
{
"empno": "7934",
"ename": "MILLER",
"job": "CLERK",
"mgr": "7782",
"hiredate": "23-1-1982",
"sal": 1300,
"comm": "",
"deptno": "10"
}
],
"getAllBonus": [],
"getAllSalgrades": [
{
"grade": "1",
"losal": 700,
"hisal": 1200
},
{
"grade": "2",
"losal": 1201,
"hisal": 1400
},
{
"grade": "3",
"losal": 1401,
"hisal": 2000
},
{
"grade": "4",
"losal": 2001,
"hisal": 3000
},
{
"grade": "5",
"losal": 3001,
"hisal": 9999
}
]
}
}
以上演示了基础的查询与数据,但实际开发中不可能只有全量查询,更多的情况下是条件查询。
在类似 REST 的系统中,你只能传递一组简单参数 -- 请求中的 query 参数和 URL 段。但是在 GraphQL 中,每一个字段和嵌套对象都能有自己的一组参数,从而使得 GraphQL 可以完美替代多次 API 获取请求。甚至你也可以给 标量(scalar)字段传递参数,用于实现服务端的一次转换,而不用每个客户端分别转换。
值的注意的是: 在 Schema 中,所有的参数到达 Resolver 后,将合并成一个Object 类型的参数,这与我们习惯中的函数形参不太一样。
上例中参数 empno 是直接在客户端直接传值。若需要动态传值时,其中一种选择就是在客户端动态的去拼接 query ,但这显然不是一个好方法。GraphQL 拥有一级方法将动态值提取到查询之外,然后作为分离的字典传进去。这些动态值即称为变量。使用变量之前,我们得做三件事:
在同一个上下文中,GraphQL 一次性请求可以获取所有所需的字段。
变更与查询的工作方式相同,在 Mutation 类型上定义一些字段,然后这些字段将作为 mutation 根字段使用,接着就能在查询中调用。
上例传参中传输的是标量类型,在操作变更提交的时候往往是一整个对象进行提交。GraphQL 也支持对象类型的参数,在 Schema 中定义输入类型与定义普通类型非常相似,只需将关键字改为 input 而不是 type 。
__EOF__
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析