Skip to content

Latest commit

 

History

History
170 lines (127 loc) · 5.39 KB

howToDesignAPI.md

File metadata and controls

170 lines (127 loc) · 5.39 KB

API规范

  • REST
  • RPC
  • GraphQL

RESTful

RESTful模式的接口 统一使用http协议

restful是面向资源的指导原则,比如说登陆和退出,如果按照人类的思想就是两个操作,动词,那么按照面向资源的方法就是提交session资源,删除session资源,所以说你要设计的就从两个动作,变成了设计一个资源,这样的好处就是抽象程度高,扩展非常容易,例如获取用户状态,就是get session,总之可以在session资源上去扩展,那么就引出了restful的基本思想:

  • 服务端和客户端分离

  • 无状态

    意思就是服务器不维护资源的状态,上下文的信息均由客户端去提供,意思就是发送一个请求的时候跟一大堆的参数,不过这一条基本上无法实现,有些资源的参数太多了,不可能全部存在客户端

  • 可缓存

  • 分层系统

    指客户端不需要知道要访问的服务端具体是谁,例如cdn,负载均衡等技术

  • 面向资源编程

  • 按需代码

    被放在客户端的代码是按需获取的,某些代码放在服务器上,需要的时候再加载到客户端上。

下面是推荐的一些具体规则:

  • 资源名称不能是动词,只能是名词
    • 一堆资源使用 examples.com/users
    • 特定资源使用 examples.com/users/admin
  • 结尾不要加/
  • 不要出现下划线_,使用-来代替
  • 路径统一都是小写
  • 避免层级过多,如果资源过多,可以转化为parms
    • bad : /students/chinese/boy/teen/zhang
    • good: /students?contry=chinese&sex=boy&year=teen&name=zhang
  • 可以将一个操作变成资源的一个属性,例如 /students/liming?active=false 就是禁掉了这个学生
  • 使用:id的模式,例如 put /students/:id/score
  • 非常规可以设置为动词,或者词组,例如 /login

RESTful的操作方法有四种:

  • GET 满足幂等性,满足安全性
  • POST 不满足,不满足
  • PUT 满足,不满足
  • DELETE 满足 不满足

这就是它用http的协议的原因。

因为post不满足幂等性,所以说,更改状态,属性的时候使用PUT,POST仅仅用来创建或者批量删除这两种场景

解决 delete 方法无法携带多个资源名的问题:

  • 发起多个delete请求
  • 操作路径中带多个id,id之间使用分隔符分割,比如 DELETE /users?id=1,2,3,4
  • 直接使用POST 方法批量删除,body中传入需要删除的资源列表

API的版本有三种形式

  • 放到URL中 v1/users
  • http header 参数中
  • form 参数中

API的命名通常可以有驼峰法(myStudent),下划线法(my_student)和短线法(my-student)

一般来说,短线法更好一些,因为短线不牵涉到输入法的切换问题

api应该提供,分页,过滤,搜索,等功能:

  • 分页,比如 /users?offset=1&limit=20
  • 过滤 ,比如 /users?fields=email,username,address
  • 排序 /users?sort=age,desc
  • 搜索 ,当一个资源的成员过多的时候,那么就需要搜索的功能,可以提供模糊搜索的功能 /users?search=age-17,sex=man 意思就是搜索大于17岁的男性

api的域名一般有两种形式:

rpc

  • 更快的传输速度,二进制传递会节省io操作
  • 跨平台,满足多语言的互相调用
  • 良好的扩展性和兼容性
  • 基于idl,通过proto3工具生成制定的语言的数据结构,服务端和客户端接口

protocol buffers 定义的数据结构:

// 定义的数据结构
message SecretInfo {
    string name = 12
    string secret_id = 89
    int64 expires = 9
}
// 定义的接口
service Cache{
    rpc somethind(ruests)returns(response){}
}

使用grpc框架,需要下面这几个步骤:

  • 定义gRPC服务
  • 生成客户端和服务器代码
  • 实现gRPC服务
  • 实现gRPC客户端

代码目录如下:

$ tree
├── client
│   └── main.go
├── helloworld
│   ├── helloworld.pb.go
│   └── helloworld.proto
└── server
    └── main.go
  • client

    存放client端代码

  • helloworld

    存放服务的idl定义

  • server

    存放server端的代码

gRPC 支持四种类型的服务方法

  • 简单模式,客户端发起一次请求,服务端响应一个数据
    service Hello{
        rpc Hi(Hirequest)returns (HelloReply){}
    }
  • 服务端数据流模式,客户端发送一个请求,服务端返回数据流响应,客户端从流中读取数据直到空
        service Hello{
            rpc Hi(helloRuest) returns (stream HelloReply){}
        }
  • 客户端数据流模式,客户端将流发送给服务器,服务器全部处理这些数据后,返回一次响应
        service Hello {
            rpc Hi(stream HelloRequest) returns (HelloReplay){}
        }
  • 双向数据流模式,客户端和服务器都是发送流,互相发送流
    service Hello {
        rpc Hi(stream HelloRequest) returns (stream HelloReplay){}
    }

graphql

可以参考一下这里 https://graphql.cn

swagger api 文档生成模式

swagger是通过定义注释,自动生成API的一种工具,通常可以使用 (go-swagger)[https://github.com/go-swagger/go-swagger] 这个工具包来完成这个任务。