审核中~
溜忙之道
首页
溜忙手册
offer之道
项目Git
写文章
登录
·
注册
登录
没有账号,去注册
注册
已有账号,去登录
博客
GraphQL
南易_站长
阅读量:5902
关注
GraphQL
# graphql 转载自:[https://www.jianshu.com/p/8971ae679201](https://www.jianshu.com/p/8971ae679201) ### 什么是 GraphQL GraphQL 是比 REST 更高效、强大和灵活的新一代 API 标准。Facebook 开发了 GraphQL 并且将其开源,目前其由一大群来自全球各地的公司和个人维护。 注意到 GraphQL 是 API 标准,不要看到 QL 结尾就以为其是一种数据库技术。 比 REST 更灵活的一种选择 REST 是目前比较流行的一种暴露服务端数据的常见方式,其简化了客户端尤其是移动端和服务器交互的流程。但是随着业务变得复杂,有些情况变得棘手: #### 移动端数量的增多,对数据的效率要求变高 移动端和 PC 端相比,是需要提高对数据获取的效率的,这个效率就是说要减少网络请求、要减少无用数据的传输。 #### 应对复杂的前端框架和平台 现在的情况是仅维护一套 API 来应对不同框架和平台的请求。PC 端一个页面比移动端一个页面展示的内容要多很多,之前后端提供给 PC 端的 API 如果直接提供给移动端来使用势必造成资源浪费。所以移动端的人会去找后端的人干一架,结果要么是后端再给移动端单独写一套 API,要么就是移动端忍受着 API 请求返回数据中存在大量冗余的数据。 #### 需要更快速地迭代更新 互联网时代最大的特色除了加班也许就是快了。好多公司在喊着小步快跑、快速试错,毕竟市场不等人。然而 REST 标准的 API 似乎很难快速地跟上这快跑的节奏。也许一个 API 刚出来,产品那边已经改了原型,界面重新设计了。这时候就要麻烦后端同学加个班把接口改一下吧。 谁在用 GraphQL 一个产品的流行,肯定是解决了目前的某些痛点。虽然 GraqhQL 目前在国内还不算流行,可是在美利坚已经有不少巨头在使用了: ![null](https://upload-images.jianshu.io/upload_images/10007410-de088e6956c03f59.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1080/format/webp) image.png GraphQL vs REST 我们来看一下对于不同 API 标准下,从服务端获取数据的区别。比如在 REST API 标准下,有三个接口: /users/ 该接口返回某用户基本信息 /users/posts 该接口返回某用户所有的文章 /users/followers 该接口返回某用户所有的关注者 ![null](https://upload-images.jianshu.io/upload_images/10007410-40addb1573c81554.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1080/format/webp) image.png 如图所示,要通过三个不同的请求才能获得某用户及其文章和关注者的信息,其中还存在很多不需要的信息。 再看一下 GraphQL API 的实现: ![null](https://upload-images.jianshu.io/upload_images/10007410-258937d80dc75b0c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1080/format/webp) image.png 客户端声明自己想要的信息,然后服务端根据请求返回相应的数据 #### 目前可见的优点: ##### 避免了 REST API 中常见的信息过多或过少的问题 信息过多是指,接口中总会存在客户端不需要的信息,信息过少是指单条接口无法满足客户端需求,需要请求多个接口才能满足需要 ##### 前端可以快速迭代 在 REST API 中,一般都是后端定义好了 API,返回固定的数据格式。当前端业务或需求发生变化时,后端很难跟上变动的节奏。如今,业务变化已经难以避免,所以当前端和后端都要相应地作出改动,这样效率势必降低。就我们公司业务来讲,很多情况下,前端一两天的改动如果再拉上后端,人多肯定要开会再加上沟通成本的问题,这个需求没个一周两周很难搞定。设想一下,如果在 GraphQL 标准下,除非大的改版,后端基本不用出人力来跟着一起需求评审,前端自己定义查询的内容就搞定了。 ##### 更深层次地进行分析 当客户端可以选择自己想请求数据的内容时,这时候就可以分析出哪些信息是用户感兴趣的,也可以更深层次地分析现有数据是如何被应用的。 此外,也可以分析出哪些信息用户不再感兴趣了。[以上转自腾讯云GraphQL简介](https://links.jianshu.com/go?to=https%3A%2F%2Fcloud.tencent.com%2Fdeveloper%2Fnews%2F238689) ##### 在 GraphQL 中,我们通过预先定义一张 Schema 和声明一些 Type 来达到上面提及的效果,我们需要知道 * 对于数据模型的抽象是通过 Type 来描述的 * 对于接口获取数据的逻辑是通过 Schema 来描述的 ### Type 对于数据模型的抽象是通过 Type 来描述的,每一个 Type 有若干 Field 组成,每个 Field 又分别指向某个 Type。 GraphQL 的 Type 简单可以分为两种,一种叫做 Scalar Type(标量类型),另一种叫做 Object Type(对象类型)。 #### Scalar Type GraphQL 中的内建的标量包含,String、Int、Float、Boolean、Enum,对于熟悉编程语言的人来说,这些都应该很好理解。 值得注意的是,GraphQL 中可以通过 Scalar 声明一个新的标量,比如: prisma(一个使用 GraphQL 来抽象数据库操作的库)中,还有 DateTime 和 ID 这两个标量分别代表日期格式和主键 在使用 GraphQL 实现文件上传接口时,需要声明一个 Upload 标量来代表要上传的文件 总之,我们只需要记住,标量是 GraphQL 类型系统中最小的颗粒,关于它在 GraphQL 解析查询结果时,我们还会再提及它。 ### Object Type 仅有标量是不够的抽象一些复杂的数据模型的,这时候我们需要使用对象类型 ```css type Article { id: ID text: String isPublished: Boolean } ``` 上面的代码,就声明了一个 Article 类型,它有 3 个 Field,分别是 ID 类型的 id,String 类型的 text 和 Boolean 类型的 isPublished。 对于对象类型的 Field 的声明,我们一般使用标量,但是我们也可以使用另外一个对象类型,比如如果我们再声明一个新的 User 类型,如下: ```css type Article { id: ID text: String isPublished: Boolean author: User } ``` Article 新增的 author 的 Field 是 User 类型, 代表这篇文章的作者。 总之,我们通过对象模型来构建 GraphQL 中关于一个数据模型的形状,同时还可以声明各个模型之间的内在关联(一对多、一对一或多对多)。 ### mongoose ![null](https://upload-images.jianshu.io/upload_images/10007410-1c11c4513d1ed943.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/611/format/webp) image.png * Schema: Mongoose 的一切始于 Schema。每个 schema 都会映射到一个 MongoDB collection ,并定义这个 collection 里的文档的构成。 定义一个 schema ```tsx const mongoose = require('mongoose'); const Schema = mongoose.Schema; let blogSchema = new Schema({ title: String, author: String, body: String, comments: [{ body: String, date: Date }], date: { type: Date, default: Date.now }, hidden: Boolean, meta: { votes: Number, favs: Number } }); ``` * Model: 基本文档数据的父类,通过集成 Schema 定义的基本方法和属性得到相关的内容. [Models](https://links.jianshu.com/go?to=http%3A%2F%2Fmongoosejs.net%2Fdocs%2Fmodels.html) 是从 `Schema` 编译来的构造函数。 它们的实例就代表着可以从数据库保存和读取的 [documents](https://links.jianshu.com/go?to=http%3A%2F%2Fmongoosejs.net%2Fdocs%2Fdocuments.html)。 从数据库创建和读取 document 的所有操作都是通过 model 进行的。 ```csharp var schema = new mongoose.Schema({ name: 'string', size: 'string' }); var Tank = mongoose.model('Tank', schema); ``` 第一个参数是跟 model 对应的集合( collection )名字的 单数 形式。 Mongoose 会自动找到名称是 model 名字 复数 形式的 collection 。 对于上例,Tank 这个 model 就对应数据库中 tanks 这个 collection。.model() 这个函数是对 schema 做了拷贝(生成了 model)。 你要确保在调用 .model() 之前把所有需要的东西都加进 schema 里了! * instance: 这就是实实在在的数据了. 通过 new Model()初始化得到.# graphql
评论
表情
发送
0
评论