当前位置: 首页 > news >正文

API 接口设计原则:RESTful 与 GraphQL

RESTful 接口

REST 的全称是 REpresentational State Transfer,是一种 Web API 的设计风格

RESTful API 设计 6 大原则

一个 RESTful 风格的接口应该满足如下的 6 点原则:

在这里插入图片描述

  • 统一接口:For example, the HTTP-based REST APIs make use of the standard HTTP methods (GET, POST, PUT, DELETE, etc.) and the URIs (Uniform Resource Identifiers) to identify resources
  • 使用 client-server 架构解耦
  • 无状态:server 不能保存与 client 的会话状态
  • 可缓存的:响应数据应该声明自己能否被缓存
  • 分层系统:采用反向代理服务器屏蔽 server 和 client
  • 按需返回可执行代码:server 能够向 client 返回一段代码用以执行

RESTful API 最佳实践

  • URL 中不要使用动词,动作交给 HTTP 的不同请求来区分
  • 状态码必须准确,错误信息就要响应对应的错误状态码

下面使用 nodejs 编写了一个简单的 web 服务,提供了查询 user 的 RESTful get 接口:

var express = require('express');
var mysql = require("mysql");
var client = mysql.createConnection({host: '192.168.93.12',user: 'root',password: 'xxx',port: '3306',database: 'big_event',
});
client.connect();
var app = express();app.get("/user/:id", (req, res) => {let { id } = req.params;client.query(`select id, username, password, email from user where id=${id}`, (err, users) => {if (err) {console.warn(err);}if (users && users.length == 1) {res.send(users[0]);} else {res.send("wrong result");}});
})app.listen(5000, () => console.log('Now browse to localhost:5000/restful'));

对于上面的 API,使用 http://localhost:5000/user/1 即可获取到 id 为 1 的 user 信息

RESTfull API 的缺点

  • 获取数据不够灵活:batch 获取数据时要发送多次请求。也容易过度获取数据:本来只需要2~3个值,结果返回了20个值
  • 弱类型:js 的类型系统薄弱,除了 number、string、array、object 等,不支持自定义类型

针对这些缺点,提出了 GraphQL

GraphQL 接口

GraphQL 是一个用于 API 的查询语言,是一个使用基于类型系统来执行查询的服务端运行时

用 GraphQL 将上面的查询接口重写如下:

const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');// 定义 GraphQL schema
const schema = buildSchema(`type User {id: Intusername: Stringpassword: Stringemail: String}type Query {user(id: Int!): User}
`);// 定义 resolver 函数,用于处理查询
const root = {user: ({ id }) => {return new Promise((resolve, reject) => {client.query(`SELECT id, username, password, email FROM user WHERE id = ${id}`, (err, result) => {if (err) {reject(err);} else {resolve(result[0]);}});});}
};const app = express();app.use('/graphql', graphqlHTTP({schema: schema,rootValue: root,graphiql: true // 启用 GraphiQL 可视化工具
}));app.listen(5000, () => {console.log('GraphQL Server is running on http://localhost:5000/graphql');
});

启动后,我们在浏览器中能够访问到一个调试界面:

在这里插入图片描述
输入查询条件:

{user(id: 1) {idusernamepassword}
}

就可以得到查询结果:

{"data": {"user": {"id": 1,"username": "wangba","password": "124bd1296bec0d9d93c7b52a71ad8d5b"}}
}

GraphQL 的优点

  • 前端变被动为主动,能够决定要获取哪些数据,不再依赖于和后端的 API 接口文档。前端能够专注于 UI 设计
  • 增减字段很容易,易于扩展
  • 批量获取数据只需要发送一次 HTTP 请求,节省了网络带宽

GraphQL 的缺点

  • 缓存实现困难

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Golang | Leetcode Golang题解之第321题拼接最大数
  • RemCom和impacket.psexec简介
  • 【计算机网络---OSI七层模型】
  • 用uniapp 及socket.io做一个简单聊天app 撤回聊天及保留聊天记录 6
  • 基于RHEL7的服务器批量安装
  • Vue前端面试基础(一)
  • ptrade排坑笔记——执行k_start.sh脚本发现没有生成日志?
  • html+css+js+jquery实现一个 飘零的树叶
  • 将元组类型的日期时间转换为字符串格式time.asctime([t])
  • RuoYi-Vue源码阅读(一):验证码模块
  • Kylin系列(二)使用
  • 缓存常见问题优化
  • 树莓派边缘计算网关搭建:集成MQTT、SQLite与Flask的完整解决方案
  • 数据结构初阶最终讲:排序
  • 使用python-pptx代码添加幻灯片:向PPT中插入新的幻灯片页面
  • Centos6.8 使用rpm安装mysql5.7
  • CSS魔法堂:Absolute Positioning就这个样
  • Git同步原始仓库到Fork仓库中
  • gops —— Go 程序诊断分析工具
  • java中的hashCode
  • js中forEach回调同异步问题
  • Spring Cloud中负载均衡器概览
  • Terraform入门 - 3. 变更基础设施
  • Windows Containers 大冒险: 容器网络
  • 阿里云Kubernetes容器服务上体验Knative
  • 初识 webpack
  • 机器学习学习笔记一
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 嵌入式文件系统
  • 小程序开发之路(一)
  • 一个完整Java Web项目背后的密码
  • 用 vue 组件自定义 v-model, 实现一个 Tab 组件。
  • (Java入门)学生管理系统
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (佳作)两轮平衡小车(原理图、PCB、程序源码、BOM等)
  • (强烈推荐)移动端音视频从零到上手(下)
  • (深度全面解析)ChatGPT的重大更新给创业者带来了哪些红利机会
  • (十六)视图变换 正交投影 透视投影
  • (四)c52学习之旅-流水LED灯
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • ***原理与防范
  • .axf 转化 .bin文件 的方法
  • .NET 3.0 Framework已经被添加到WindowUpdate
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .net core 微服务_.NET Core 3.0中用 Code-First 方式创建 gRPC 服务与客户端
  • .NET Core 中插件式开发实现
  • .NET 读取 JSON格式的数据
  • .Net 高效开发之不可错过的实用工具
  • .net 获取某一天 在当月是 第几周 函数
  • .skip() 和 .only() 的使用
  • ??myeclipse+tomcat
  • @for /l %i in (1,1,10) do md %i 批处理自动建立目录
  • @NoArgsConstructor和@AllArgsConstructor,@Builder
  • @property括号内属性讲解