网络配置综合

graphql

2019-05-18  本文已影响0人  三天两觉_

什么是GraphQL

GraphQL是比REST更高效、强大和灵活的新一代API标准。Facebook开发了GraphQL并且将其开源,目前其由一大群来自全球各地的公司和个人维护。

注意到GraphQL是API标准,不要看到QL结尾就以为其是一种数据库技术。

比REST更灵活的一种选择

REST是目前比较流行的一种暴露服务端数据的常见方式,其简化了客户端尤其是移动端和服务器交互的流程。但是随着业务变得复杂,有些情况变得棘手:

移动端数量的增多,对数据的效率要求变高

移动端和PC端相比,是需要提高对数据获取的效率的,这个效率就是说要减少网络请求、要减少无用数据的传输。

应对复杂的前端框架和平台

现在的情况是仅维护一套API来应对不同框架和平台的请求。PC端一个页面比移动端一个页面展示的内容要多很多,之前后端提供给PC端的API如果直接提供给移动端来使用势必造成资源浪费。所以移动端的人会去找后端的人干一架,结果要么是后端再给移动端单独写一套API,要么就是移动端忍受着API请求返回数据中存在大量冗余的数据。

需要更快速地迭代更新

互联网时代最大的特色除了加班也许就是快了。好多公司在喊着小步快跑、快速试错,毕竟市场不等人。然而REST标准的API似乎很难快速地跟上这快跑的节奏。也许一个API刚出来,产品那边已经改了原型,界面重新设计了。这时候就要麻烦后端同学加个班把接口改一下吧。

谁在用GraphQL

一个产品的流行,肯定是解决了目前的某些痛点。虽然GraqhQL目前在国内还不算流行,可是在美利坚已经有不少巨头在使用了:


image.png

GraphQL vs REST
我们来看一下对于不同API标准下,从服务端获取数据的区别。比如在REST API标准下,有三个接口:

/users/

该接口返回某用户基本信息

/users/posts

该接口返回某用户所有的文章

/users/followers

该接口返回某用户所有的关注者


image.png

如图所示,要通过三个不同的请求才能获得某用户及其文章和关注者的信息,其中还存在很多不需要的信息。

再看一下GraphQL API的实现:


image.png

客户端声明自己想要的信息,然后服务端根据请求返回相应的数据

目前可见的优点:

避免了REST API中常见的信息过多或过少的问题

信息过多是指,接口中总会存在客户端不需要的信息,信息过少是指单条接口无法满足客户端需求,需要请求多个接口才能满足需要

前端可以快速迭代

在REST API中,一般都是后端定义好了API,返回固定的数据格式。当前端业务或需求发生变化时,后端很难跟上变动的节奏。如今,业务变化已经难以避免,所以当前端和后端都要相应地作出改动,这样效率势必降低。就我们公司业务来讲,很多情况下,前端一两天的改动如果再拉上后端,人多肯定要开会再加上沟通成本的问题,这个需求没个一周两周很难搞定。设想一下,如果在GraphQL标准下,除非大的改版,后端基本不用出人力来跟着一起需求评审,前端自己定义查询的内容就搞定了。

更深层次地进行分析

当客户端可以选择自己想请求数据的内容时,这时候就可以分析出哪些信息是用户感兴趣的,也可以更深层次地分析现有数据是如何被应用的。
此外,也可以分析出哪些信息用户不再感兴趣了。以上转自腾讯云GraphQL简介

在GraphQL中,我们通过预先定义一张Schema和声明一些Type来达到上面提及的效果,我们需要知道

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

仅有标量是不够的抽象一些复杂的数据模型的,这时候我们需要使用对象类型

type Article {
  id: ID
  text: String
  isPublished: Boolean
}

上面的代码,就声明了一个Article类型,它有3个Field,分别是ID类型的id,String类型的text和Boolean类型的isPublished。

对于对象类型的Field的声明,我们一般使用标量,但是我们也可以使用另外一个对象类型,比如如果我们再声明一个新的User类型,如下:

type Article {
  id: ID
  text: String
  isPublished: Boolean
  author: User
}

Article新增的author的Field是User类型, 代表这篇文章的作者。

总之,我们通过对象模型来构建GraphQL中关于一个数据模型的形状,同时还可以声明各个模型之间的内在关联(一对多、一对一或多对多)。

mongoose

image.png
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
    }
  });
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 里了!

上一篇 下一篇

猜你喜欢

热点阅读