首页 » PHP教程 » php接口作风技巧_浅谈三种API设计风格RPCRESTGraphQL

php接口作风技巧_浅谈三种API设计风格RPCRESTGraphQL

duote123 2024-12-16 0

扫一扫用手机浏览

文章目录 [+]

正文

1. RPC

这是最常见的办法,RPC说的是本地调用远程的方法,面向的是过程。

php接口作风技巧_浅谈三种API设计风格RPCRESTGraphQL

RPC形式的API组织形态是类和方法,或者说领域和行为。
因此API的命名每每是一个动词,比如GetUserInfo和CreateUser。
由于URI会非常多而且每每没有一些约定规范,以是须要有详细的文档。
也是由于无拘无束,HTTP方法基本只用GET和POST,设计起来比较大略。

这里就不贴例子了,估计超过50%的API是这种风格的。

php接口作风技巧_浅谈三种API设计风格RPCRESTGraphQL
(图片来自网络侵删)

2. REST

是一种架构风格,有四个级别的成熟度:

级别0:定义一个 URI,所有操作是对此 URI 发出的 POST 要求。
级别1:为各个资源单独创建 URI。
级别2:利用 HTTP 方法来定义对资源实行的操作。
级别3:利用超媒体(HATEOAS)。

级别0实在便是类RPC的风格,级别3是真正的REST,大多数号称REST的API在级别2。
REST实现一些要点包括:

REST形式的API组织形态是资源和实体,统统环绕资源(级别1的要点)。
设计流程包括:确定API供应的资源确定资源之间的关系根据资源类型和关系确定资源URI构造确定资源的构造体会定义一些标准方法(级别2的要点),然后把标准方法映射到实现(比如HTTP Method):GET:获取资源详情或资源列表。
对付collection类型的URI(比如/customers)便是获取资源列表,对付item类型的URI(比如/customers/1)便是获取一个资源。
POST:创建资源,要求体是新资源的内容。
每每POST是用于为凑集新增资源。
PUT:创建或修正资源,要求体是新资源的内容。
每每PUT用于单个资源的新增或修正。
实现上必须幂等。
PATCH:部分修正资源,要求体是修正的那部分内容。
PUT一样平常哀求提交全体资源进行修正,而PATCH用于修正部分内容(比如某个属性)。
DELETE:移除资源。
和GET一样,对付collection类型的URI(比如/customers)便是删除所有资源,对付item类型的URI(比如/customers/1)便是删除一个资源。

须要考虑资源之间的导航(级别3的要点,比如利用HATEOAS,HATEOAS是Hypertext as the Engine of Application State的缩写)。
有了资源导航,客户端乃至可能不须要参阅文档就可以找到更多对自己有用的资源,不过HATEOAS没有固定的标准,比如:

{ \公众content\公众: [ { \"大众price\公众: 499.00, \公众description\"大众: \"大众Apple tablet device\"大众, \公众name\"大众: \"大众iPad\公众, \"大众links\"大众: [ { \"大众rel\"大众: \"大众self\公众, \"大众href\公众: \"大众http://localhost:8080/product/1\"大众 } ], \"大众attributes\公众: { \公众connector\"大众: \"大众socket\"大众 } }, { \"大众price\"大众: 49.00, \公众description\"大众: \"大众Dock for iPhone/iPad\公众, \"大众name\"大众: \"大众Dock\"大众, \公众links\"大众: [ { \"大众rel\"大众: \"大众self\"大众, \"大众href\"大众: \"大众http://localhost:8080/product/3\"大众 } ], \"大众attributes\公众: { \"大众connector\"大众: \"大众plug\"大众 } } ], \公众links\"大众: [ { \公众rel\"大众: \"大众product.search\"大众, \"大众href\公众: \"大众http://localhost:8080/product/search\"大众 } ]}

Spring框架也供应了相应的支持:https://spring.io/projects/spring-hateoas

@RestControllerpublic class GreetingController { private static final String TEMPLATE = \公众Hello, %s!\"大众; @RequestMapping(\"大众/greeting\"大众) public HttpEntity<Greeting> greeting( @RequestParam(value = \公众name\"大众, required = false, defaultValue = \"大众World\"大众) String name) { Greeting greeting = new Greeting(String.format(TEMPLATE, name)); greeting.add(linkTo(methodOn(GreetingController.class).greeting(name)).withSelfRel()); return new ResponseEntity<>(greeting, HttpStatus.OK); }}

产生如下的结果:

除了之条件到的几个要点,REST API的设计还有一些小点:必须无状态的,相互独立的,不区分顺序的API须要有同等的接口来解耦客户端和做事实现,如果基于HTTP那么务必利用HTTPMethod来操作资源,而且只管即便利用HTTP相应码来处理缺点须要只管即便考虑缓存、版本掌握、内容协商、部分相应等实现

可以说REST的API设计是须要设计感的,须要仔细来思考API的资源,资源之间的关系和导航,URI的定义等等。
对付一套设计精良的REST API,实在客户端只要知道可用资源清单,每每就可以轻易根据约定俗成的规范以及导航探索出大部分API。
比较讽刺的是,有很多网站给前端和客户真个接口是REST的,爬虫开拓者可以轻易探索到所有接口,乃至一些内部接口,毕竟猜一下REST的接口比RPC的接口随意马虎的多。

作为补充,下面再列几个有关REST API设计大家争议谈论纠结的比较多的几个方面。

3. GraphQL

如果说RPC面向过程,REST面向资源,那么GraphQL便是面向数据查询了。
GraphQL 既是一种用于 API 的查询措辞也是一个知足你数据查询的运行时。
GraphQL 对你的 API 中的数据供应了一套易于理解的完全描述,使得客户端能够准确地得到它须要的数据,而且没有任何冗余,也让 API 更随意马虎地随着韶光推移而演进,还能用于构建强大的开拓者工具。

采取GraphQL,乃至不须要有任何的接口文档,在定义了Schema之后,做事端实现Schema,客户端可以查看Schema,然后构建出自己须要的查询要求来得到自己须要的数据。

image

## Schemas must have at least a query root type#schema { query: Query}type Query { characters( episode: Episode ) : [Character] human( # The id of the human you are interested in id : ID! ) : Human droid( # The non null id of the droid you are interested in id: ID! ): Droid}# One of the films in the Star Wars Trilogyenum Episode { # Released in 1977 NEWHOPE # Released in 1980. EMPIRE # Released in 1983. JEDI}# A character in the Star Wars Trilogyinterface Character { # The id of the character. id: ID! # The name of the character. name: String! # The friends of the character, or an empty list if they # have none. friends: [Character] # Which movies they appear in. appearsIn: [Episode]! # All secrets about their past. secretBackstory : String @deprecated(reason : \公众We have decided that this is not canon\公众)}# A humanoid creature in the Star Wars universe.type Human implements Character { # The id of the human. id: ID! # The name of the human. name: String! # The friends of the human, or an empty list if they have none. friends: [Character] # Which movies they appear in. appearsIn: [Episode]! # The home planet of the human, or null if unknown. homePlanet: String # Where are they from and how they came to be who they are. secretBackstory : String @deprecated(reason : \"大众We have decided that this is not canon\"大众)}# A mechanical creature in the Star Wars universe.type Droid implements Character { # The id of the droid. id: ID! # The name of the droid. name: String! # The friends of the droid, or an empty list if they have none. friends: [Character] # Which movies they appear in. appearsIn: [Episode]! # The primary function of the droid. primaryFunction: String # Construction date and the name of the designer. secretBackstory : String @deprecated(reason : \"大众We have decided that this is not canon\"大众)}

采取GraphQL Playground(https://github.com/prisma/graphql-playground)

实在便是__schema:

然后我们可以根据客户真个UI须要自己来定义查询要求,做事端会根据客户端给的构造来返回数据:

再来看看Github供应的GraphQL(更多参考https://developer.github.com/v4/guides/):

查询出了末了的三个repo:

GraphQL便是通过Schema来明确数据的能力,做事端供应统一的唯一的API入口,然后客户端来见告做事端我要的详细数据构造(基本可以说不须要有API文档),有点客户端驱动做事真个意思。
虽然客户端灵巧了,但是GraphQL做事真个实现比较繁芜和痛楚的,GraphQL不能替代其它几种设计风格,并不是传说中的REST 2.0。

小结

不才列情形考虑RPC风格的API或说是RPC:

倾向内部的API没有太多的韶光考虑API的设计或没有架构师供应的API很难进行资源、工具抽象对性能有高哀求

不才列情形考虑REST风格:

倾向外部API供应的API天生环绕资源、工具、管理展开不能耦合客户端实现资源的CRUD是可以对齐的(功能完全的)

不才列情形考虑GraphQL:

客户端对付数据的需求多变数据具有图的特点

作者:零壹技能栈

链接:https://www.jianshu.com/p/5ef018004756

标签:

相关文章

php生成jsontree技巧_文件树生成

图片来源于网络,侵删手动写比较麻烦,可以借助一些工具实现。VSCode中有些类似的插件,比如:file-tree-generato...

PHP教程 2024-12-18 阅读0 评论0