Git Product home page Git Product logo

gg-apidesignguide's People

Contributors

denghuiquan avatar

Stargazers

 avatar

Watchers

 avatar  avatar

gg-apidesignguide's Issues

GAD04: Custom Methods 自定义方法

自定义方法

目录
HTTP Mapping HTTP映射
Use Cases 用例
Common Custom Methods 公共自定义方法

本章将讨论如何使用API设计的自定义方法。

除了5种标准方法外,自定义方法是指API方法。它们只能用于不能通过标准方法容易表达的功能。在一般情况下,API设计者应该选择标准方法优先于自定义方法,只要它是可行的。标准方法具有较简单和明确的语义,大多数开发人员都熟悉,所以它们更容易使用和更少的错误倾向。标准方法的另一个优点是API平台对标准方法有更好的理解和支持,如计费、错误处理、日志记录、监控等。

自定义方法可以与资源、集合或服务关联。它可以采取任意请求并返回任意响应,也支持流请求和响应。


HTTP mapping Http映射

对于自定义方法,他们应该使用以下通用HTTP映射:

https://service.name/v1/some/resource/name:customVerb

使用 : 而不是 / 将自定义谓词与资源名称分隔开来的原因是为了支持(更多的)任意路径。例如,撤销删除一个文件可以映射到 POST /files/ a/long/file/name:undelete

选择HTTP映射时应使用以下准则:

  • 自定义方法应该使用HTTP POST谓词,因为它具有最灵活的语义。
  • 自定义方法不应该使用HTTP PATCH,但可以使用其他HTTP谓词。在这种情况下,方法必须遵循标准的HTTP语义的动词。
  • 值得注意的是,使用HTTP GET的自定义方法必须是幂等的并且没有副作用。例如,在资源上实现特殊视图的自定义方法应该使用HTTP GET
  • 接收与自定义方法关联的资源或集合的资源名称的请求消息字段应映射到URL路径。
  • URL路径必须以一个由后跟自定义动词的冒号:组成的后缀结尾。
  • 如果用于自定义方法的HTTP谓词允许HTTP请求体(POST、PUT、PATCH或自定义HTTP谓词),则该自定义方法的HTTP配置必须使用body:“*”子句和所有剩余的请求消息字段将映射到HTTP请求体。
  • 如果用于自定义方法的HTTP谓词不接受HTTP请求体(GET,DELETE),则该方法的HTTP配置不能完全使用“body子句”,其余所有请求消息字段应映射到url查询参数。

Warning: 如果服务实现多个API,API生产者必须小心创建服务配置,避免API之间的自定义谓词冲突。

// This is a service level custom method.
rpc Watch(WatchRequest) returns (WatchResponse) {
  // Custom method maps to HTTP POST. All request parameters go into body.
  option (google.api.http) = {
    post: "/v1:watch"
    body: "*"
  };
}

// This is a collection level custom method.
rpc ClearEvents(ClearEventsRequest) returns (ClearEventsResponse) {
  option (google.api.http) = {
    post: "/v3/events:clear"
    body: "*"
  };
}

// This is a resource level custom method.
rpc CancelEvent(CancelEventRequest) returns (CancelEventResponse) {
  option (google.api.http) = {
    post: "/v3/{name=events/*}:cancel"
    body: "*"
  };
}

// This is a batch get custom method.
rpc BatchGetEvents(BatchGetEventsRequest) returns (BatchGetEventsResponse) {
  // The batch get method maps to HTTP GET verb.
  option (google.api.http) = {
    get: "/v3/events:batchGet"
  };
}

Use Cases 用例

一些额外的场景,自定义方法可能是正确的选择:

  • 重启虚拟机。 该设计供选方案可以是在重启集合中创建重启资源,这感觉不成比例的复杂,或“虚拟机具有可变状态,也就是说客户端可以从运行状态到重启状态的更新,其他的状态转换是可能的这样的开放的问题。 此外,重新启动是一个众所周知的概念,可以很好地转化为一个自定义的方法,直观地满足开发者的期望。

  • 发送邮件。 创建电子邮件信息不一定要发送(草稿)。相比于设计供选方案(邮件移动到“发件箱”集合)的自定义方法的优点是更容易被API用户发现(了解),模型的概念更直接。

  • 提拔员工。 如果作为一个标准的update方法来实现,客户必须复制公司政策,以确保晋升过程中发生的正确的水平,在同一职业阶梯等。

  • 批批处理方法。 对于性能关键方法,提供自定义批处理方法以减少每次请求开销可能是有帮助的。例如,accounts.locations.batchget

    标准方法比自定义方法更适合的几个例子:

  • 使用不同查询参数查询资源(使用标准列表(list)过滤方法)。

  • 简单的资源属性更改(使用带字段掩码的标准更新(update)方法)。

  • 驳回通知(使用标准删除(delete)方法)。


Common Custom Methods 公共自定义方法

下面是有用的精选常用列表或自定义方法的名称。API设计师应该在引入自己的API之前考虑这些名称,以促进一致性。

方法名称 自定义谓词 HTTP谓词 注释
Cancel :cancel POST 取消未完成的操作(生成、计算等)
BatchGet :batchGet GET 多资源批处理。(详见清单描述
Move :move POST 将资源从一个父资源移动到另一个父资源。
Search :search GET 替代不包含列表语义的数据获取列表。
Undelete :undelete POST 还原以前删除的资源。推荐保留期为30天。

Editor huiquan @denghuiquan
2017-04-18 23:30 pM.

GAD02: Resource Names 资源名称

资源名称

目录
Full Resource Name 完整资源名称
RelativeResource Name 相对资源名称
Resource ID 资源ID
Collection ID 集合ID
Resource Name vs URL 资源名称与URL的差异
Resource Name as String 字符串资源名称

在面向资源的API中,资源是命名实体,资源名称是它们的标识符。每个资源必须有它唯一的资源名称。资源名称由资源本身的ID、任何父资源的ID和它的API服务名称组成。下面我们来看一下资源ID以及如何构造资源名称。

gRPC API应该使用scheme-lessURIS作为资源名称。他们通常遵循其余的URL约定和行为就像网络文件路径。他们可以很容易地映射到REST URLs:详情见标准方法部分。

一个集合是一种包含同类型子资源列表的特殊的资源。例如,目录是文件资源的集合。集合的资源ID称为集合ID。

资源名称是使用集合ID和资源ID分层组织的,用正斜杠分隔。如果资源包含子资源,子资源的名字是通过指定父资源名称后跟子资源的ID,用正斜杠分隔形成的。

例子1:存储服务有一个桶(bucket)集合,每个桶都有一个对象(object)集合:
API Service Name | Collection ID | Resource ID | Collection ID | Resource ID
//storage.googleapis.com | /buckets | /bucket-id | /objects | /object-id

例子2:一个邮件服务有一个用户集合。每个用户有一个设置子资源,同时设置子资源有一系列其他的子资源,包括customFrom:
API Service Name | Collection ID | Resource ID | Resource ID | Resource ID
//mail.googleapis.com | /users | /[email protected] | /settings | /customFrom

API生产者可以选择资源和集合ID的任何可接受值,只要它们在资源层次结构中是唯一的。您可以在下面找到更多选择适当的资源和集合ID的指导方针。

通过拆分资源名称,如名称、拆分(“/”)n,假设没有片段段包含任何正向斜杠,那么就可以得到单独的集合ID和资源ID。


完整资源名称

由DNS兼容的API服务名称和资源路径组成的无计划(scheme-less )URI。资源路径也称为相对资源名称。例如:
"//library.googleapis.com/shelves/shelf1/books/book2"

API服务名称是为客户定位API服务端点的;它可能是一个指向内部唯一的服务的假DNS名称。如果API服务名称在上下文中是明显可见的,则通常使用相对资源名称。


相对资源名称

一个不是由”/“开头的URI路径(path-noscheme)。它标识API服务中的资源。例如:
"shelves/shelf1/books/book2"


资源ID

一个标识其父资源内的资源的非空URI片段(segment-nz-nc),请参见上面的例子。

资源名称中的尾随资源id可能有多个URI片段。例如:
Collection ID | Resource ID
files | /source/py/parser.py

API服务在可行的时候应该使用URL友好的资源ID。资源ID必须清楚地记录是否由客户机、服务器分配,或者不是。例如,文件名通常由客户端分配,而电子邮件ID通常由服务器分配。


集合ID

一个标识其父资源内的集合资源的非空URI段(segment-nz-nc),请参见上面的例子。

由于集合ID经常出现在生成的客户端库中,所以它们必须符合以下要求:

  • 必须是有效的C / C++标识符。
  • 必须用复数形式与小写开头的驼峰格式。
  • 必须使用清晰简明的英语词汇。
  • 避免或限制使用过于笼统的词汇。
    例如: RowValue好过Value。下列词汇应严格无条件避免:
  • Element
  • Entry
  • Instance
  • Item
  • Object
  • Resource
  • Type
  • Value

资源名称与URL的差异

虽然完整资源名称类似正常网址,他们却不是同样的东西。可以通过不同版本的API和不同的API协议暴露单个资源。完整的资源名称没有指定这些信息,因此必须将其映射到特定的协议和API版本以供实际使用。

通过REST API使用完整资源名称,必须在服务名称之前添加HTTPS方案将其转换为其他URL,在资源路径之前添加API主版本,和经URL转义后的资源路径。例如:

// This is a calendar event resource name.
*"//calendar.googleapis.com/users/john smith/events/123"*

// This is the corresponding HTTP URL.
*"https://calendar.googleapis.com/v3/users/john%20smith/events/123"*

字符串资源名称

谷歌API必须使用字符串来表示资源名称,除非向后兼容是一个问题。资源名称应像正常文件路径一样处理,它们不支持%编码。

对于资源定义,第一个字段应该是资源名称的字符串字段,它应该被称为名称。

注意:其他与名城相关字段应避免混淆的名字,如display_namefirst_namelast_namefull_name

例如:

service LibraryService {
  rpc GetBook(GetBookRequest) returns (Book) {
    option (google.api.http) = {
      get: "/v1/{name=shelves/*/books/*}"
    };
  };
  rpc CreateBook(CreateBookRequest) returns (Book) {
    option (google.api.http) = {
      post: "/v1/{parent=shelves/*}/books"
      body: "book"
    };
  };
}

message Book {
  // Resource name of the book. It must have the format of "shelves/*/books/*".
  // For example: "shelves/shelf1/books/book2".
  string name = 1;

  // ... other properties
}

message GetBookRequest {
  // Resource name of a book. For example: "shelves/shelf1/books/book2".
  string name = 1;
}

message CreateBookRequest {
  // Resource name of the parent resource where to create the book.
  // For example: "shelves/shelf1".
  string parent = 1;
  // The Book resource to be created. Client must not set the `Book.name` field.
  Book book = 2;
}

注意:对于资源名称的一致性,前面的斜杠不能被任何URL模板变量捕获。例如,URL模板"/v1/{name=shelves/*/books/*}" 必须用"/v1{name=/shelves/*/books/*}"代替。

Editor huiquan @denghuiquan
2017-03-26 14:20pM.

GAD05: Standard Fields 标准字段

标准字段

本节描述了一组标准的消息字段定义,当需要类似的概念时应使用该字段。这将确保相同的概念具有相同的名称和语义在不同的API。

Name Type Description
name string The name field should contain the relative resource name.
parent string For resource definitions and List/Create requests, the parent field should contain the parent relative resource name.
create_time Timestamp The creation timestamp of an entity.
update_time Timestamp The last update timestamp of an entity. Note: update_time is updated when create/patch/delete operation is performed.
delete_time Timestamp The deletion timestamp of an entity, only if it supports retention.
time_zone string The time zone name. It should be an IANA TZ name, such as "America/Los_Angeles". For more information, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones.
region_code string The Unicode country/region code (CLDR) of a location, such as "US" and "419". For more information, see http://www.unicode.org/reports/tr35/#unicode_region_subtag.
language_code string The BCP-47 language code, such as "en-US" or "sr-Latn". For more information, see http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
display_name string The display name of an entity.
title string The official name of an entity, such as company name. It should be treated as the formal version of display_name.
description string One or more paragraphs of text description of an entity.
filter string The standard filter parameter for List methods.
query string The same as filter if being applied to a search method (ie :search)
page_token string The pagination token in the List request.
page_size int32 The pagination size in the List request.
total_size int32 The total count of items in the list irrespective of pagination.
next_page_token string The next pagination token in the List response. It should be used as page_token for the following request. An empty value means no more result.
order_by string Specifies the result ordering for List requests.
request_id string A unique string id used for detecting duplicated requests.
resume_token string An opaque token used for resuming a streaming request.
labels map<string, string> Represents Cloud resource labels.
deleted bool If a resource allows undelete behavior, it must have a deleted field indicating the resource is deleted.
show_deleted bool If a resource allows undelete behavior, the corresponding List method must have a show_deleted field so client can discover the deleted resources.
update_mask FieldMask It is used for Update request message for performing partial update on a resource.
validate_only bool If true, it indicates that the given request should only be validated, not executed.

markdown table demo

Command Description
git status List all new or modified files
git diff Show file differences that haven't been staged

Editor huiquan @denghuiquan
2017-04-18 23:30 pM.

GAD03: Standard Methods 标准方法

标准方法

目录
List 列表
Get 获取
Create 创建
Update 更新
Delete 删除

本章定义了标准方法的概念,包括列表、获取、创建、更新和删除。之所以有标准方法的原因是许多API方法在广泛的API之间有非常相似的语义。通过将这些类似的API融合到标准方法中,我们可以大大减少复杂性和提高一致性。在谷歌API库中的API方法中,超过70%是标准方法,这使得它们更容易学习和使用。

下表描述了如何将它们映射到其他的方法,也被称为CRUD方法:
Method | HTTP Mapping | HTTP Request Body | HTTP Response Body
List | GET | | Empty | Resource* list
Get | GET | | Empty | Resource*
Create | POST | | Resource | Resource*
Update | PUT or PATCH | | Resource | Resource*
Delete | DELETE | | Empty | Empty**

*从列表,获取,创建和更新方法中返回的资源可能包含部分数据,如果方法支持字段掩码(标记),该字段指定要返回的字段子集。在某些情况下,API平台为所有方法原生支持字段掩码(标记)。

*不立即删除资源(如更新标志或创建长时间删除操作)的删除方法返回的响应应包含长运行操作或修改后的资源。

一个标准方法也可以为在单个API调用的时间范围内未完成的请求返回一个长运行操作。

以下各节详细描述了每个标准方法。这些示例显示了在.proto文件中定义的方法,这些方法具有针对http映射的特殊注释。您可以在谷歌API库中找到许多生产中使用标准方法的例子。


List

列表(List)方法将集合名称和零或多个参数作为输入,并返回与输入匹配的资源列表。它通常也被用于搜索资源。

列表适合于单个集合的数据,这些集合的大小是有界的,也不缓存。对于更广泛的情况,应使用自定义搜索(Search)方法。

一个批获取(如一个需要多个资源ID并返回这些ID对应的每个对象的方法)应该作为一个自定义Batchget实现的方法,而不是一个列表。但是,如果已有已提供相同功能的列表(List)方法,则可以重用列表(List)方法来达到此目的。如果你使用的是自定义batchget方法,它应该被映射到HTTP GET。

适用类型:分页,结果排序。
适用命名约定:筛选字段、结果字段。

HTTP的映射:

  • 列表(List)方法必须使用HTTP GET谓词。
  • 请求消息字段接收将被列出资源的集合的名称,该映射应映射到URL路径。如果集合名称映射到URL路径,URL模板的最后一段(集合ID)必须是文本。
  • 所有剩余的请求消息字段应映射到url查询参数。
  • 没有请求体,API配置不能声明正文子句。
  • 响应主体应该包含一个资源列表以及可选元数据。
// Lists all the books on a given shelf.
rpc ListBooks(ListBooksRequest) returns (ListBooksResponse) {
  // List method maps to HTTP GET.
  option (google.api.http) = {
    // The `parent` captures the parent resource name, such as "shelves/shelf1".
    get: "/v1/{parent=shelves/*}/books"
  };
}

message ListBooksRequest {
  // The parent resource name, for example, "shelves/shelf1".
  string parent = 1;

  // The maximum number of items to return.
  int32 page_size = 2;

  // The next_page_token value returned from a previous List request, if any.
  string page_token = 3;
}

message ListBooksResponse {
  // The field name should match the noun "books" in the method name.  There
  // will be a maximum number of items returned based on the page_size field
  // in the request.
  repeated Book books = 1;

  // Token to retrieve the next page of results, or empty if there are no
  // more results in the list.
  string next_page_token = 2;
}

Get

GET方法接收资源名称、零个或多个参数,并返回指定的资源。

HTTP的映射:

  • GET方法必须使用HTTP GET谓词。
  • 接收资源名称的请求消息字段应映射到URL路径。
  • 所有剩余的请求消息字段应映射到url查询参数。
  • 没有请求体,API配置不能声明正文子句。
  • 返回的资源应映射到整个响应体。
// Gets the specified book.
rpc GetBook(GetBookRequest) returns (Book) {
  // Get maps to HTTP GET. Resource name is mapped to the URL. No body.
  option (google.api.http) = {
    // Note the URL template variable which captures the multi-segment resource
    // name of the requested book, such as "shelves/shelf1/books/book2"
    get: "/v1/{name=shelves/*/books/*}"
  };
}

message GetBookRequest {
  // The field will contain name of the resource requested, for example:
  // "shelves/shelf1/books/book2"
  string name = 1;
}

Create

创建(Create)方法接收集合名称、资源和零或多个参数。它在指定的集合中创建一个新资源,并返回新创建的资源。
如果API支持一次创建多个资源,它应该为每一种可以创建的资源的类型准备一个创建(Create)方法。

HTTP的映射:

  • 创建(Create)方法必须使用HTTP POST动词。
  • 请求消息应该有一个名为parent的字段来接收要创建资源的父资源名称。
  • 所有剩余的请求消息字段应映射到url查询参数。
  • 请求可能包含一个名为_id以允许调用者选择客户分配的ID。该字段必须映射到URL查询参数。
  • 包含资源的请求消息字段应映射到请求主体。如果请求体的HTTP配置条款用于创建方法,请求体:“<resource_field>“表单必须用。
  • 返回的资源应映射到整个响应体。

如果创建方法支持客户端指定的资源名称和资源已经存在,它要么失败(推荐错误google.rpc.Code.ALREADY_EXISTS),要么使用不同的服务器指定的资源名称,同时文档应该讲清楚创建的资源名称可能与传入的资源名称不同。

rpc CreateBook(CreateBookRequest) returns (Book) {
  // Create maps to HTTP POST. URL path as the collection name.
  // HTTP request body contains the resource.
  option (google.api.http) = {
    // The `parent` captures the parent resource name, such as "shelves/1".
    post: "/v1/{parent=shelves/*}/books"
    body: "book"
  };
}

message CreateBookRequest {
  // The parent resource name where the book to be created.
  string parent = 1;

  // The book id to use for this book.
  string book_id = 3;

  // The book resource to create.
  // The field name should match the Noun in the method name.
  Book book = 2;
}

rpc CreateShelf(CreateShelfRequest) returns (Shelf) {
  option (google.api.http) = {
    post: "/v1/shelves"
    body: "shelf"
  };
}

message CreateShelfRequest {
  Shelf shelf = 1;
}

Update

更新(Update)方法接收包含资源和零或多个参数的请求消息。它更新指定的资源及其属性,并返回更新的资源。
可变资源属性应该由更新(Update)方法更改,除包含资源名称或父属性的属性除外。任何重命名或移动资源的功能不能在更新(Update)方法中发生,而是应该由自定义方法处理。

HTTP的映射:

  • 标准的更新Update方法应该支持部分资源的更新,并使用HTTP动词PATCH与Fieldmask字段命名update_mask
  • 更新(Update)方法,需要更先进的修补(patching)语义,如添加到重复字段,应通过自定义方法提供。
  • 如果更新(Update)方法只支持完全资源更新,则必须使用HTTP谓词PUT。 但是,非常遗憾,因为它在添加新资源字段时存在向后兼容性问题。
  • 接收资源名称的消息字段必须映射到URL路径。字段可能在资源消息本身中。
  • 包含资源的请求消息字段必须映射到请求主体。
  • 所有剩余的请求消息字段必须映射到url查询参数。
  • 响应消息必须是更新的资源本身。

如果API接受客户端分配的资源名称,服务器可能允许客户端指定不存在的资源名称并创建新资源。否则,更新方法将因不存在资源名称失败。如果这是唯一的错误条件则应该使用错误代码NOT_FOUND

具有支持资源创建的更新(Update)方法的API也应该提供创建(Create)方法。理由是,如果更新(Update)方法是唯一的方法来做到这一点,那就不清楚如何创建资源了。

rpc UpdateBook(UpdateBookRequest) returns (Book) {
  // Update maps to HTTP PATCH. Resource name is mapped to a URL path.
  // Resource is contained in the HTTP request body.
  option (google.api.http) = {
    // Note the URL template variable which captures the resource name of the
    // book to update.
    patch: "/v1/{book.name=shelves/*/books/*}"
    body: "book"
  };
}

message UpdateBookRequest {
  // The book resource which replaces the resource on the server.
  Book book = 1;

  // The update mask applies to the resource. For the `FieldMask` definition,
  // see https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#fieldmask
  FieldMask update_mask = 2;
}

Delete

删除(Delete)方法接收资源名称和零个或多个参数,并删除指定资源的删除(s)或计划(s)。删除(Delete)方法应该返回google.protobuf.Empty

注意,API不应依赖于删除方法返回的任何信息,因为它不能多次调用。

HTTP的映射:

  • 删除(Delete)方法必须使用HTTP谓词DELETE。
  • 接收资源名称的请求消息字段应映射到URL路径。
  • 所有剩余的请求消息字段应映射到url查询参数。
  • 没有请求体,API配置不能声明正文子句。
  • 如果删除(Delete)方法立即移除资源,它应该返回一个空响应。
  • 如果删除(Delete)方法启动了长时间运行操作,则应返回长时间运行操作。
  • 如果删除(Delete)方法只标记资源被删除,它应该返回更新的资源。

对删除(Delete)方法的调用实际上是幂等的,但不需要产生相同的响应。任何数量的删除(Delete)请求应导致资源(最终)删除,但只有第一个请求会导致一个成功的代码,后续请求的结果应返回一个google.rpc.Code.NOT_FOUND

rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {
  // Delete maps to HTTP DELETE. Resource name maps to the URL path.
  // There is no request body.
  option (google.api.http) = {
    // Note the URL template variable capturing the multi-segment name of the
    // book resource to be deleted, such as "shelves/shelf1/books/book2"
    delete: "/v1/{name=shelves/*/books/*}"
  };
}

message DeleteBookRequest {
  // The resource name of the book to be deleted, for example:
  // "shelves/shelf1/books/book2"
  string name = 1;
}

Editor huiquan @denghuiquan
2017-04-05 15:25pM.

GAD01: Resource Oriented Design 面向资源的设计

Resource Oriented Design 面向资源的设计


目录

  • 什么是REST API?
  • 设计流程
  • 方法
  • 例子
  • Gmail API
  • Google Cloud Pub/Sub API

这个设计指南的目标是要帮助开发者设计出简单、一致、而且易用的网络化接口(API)。同时,它也有助于融合基于HTTP的协议的REST API和基于套接字协议的RPC API的设计。

传统上,人们在API 接口和方法方面来设计RPC API,如CORBA和Windows COM。随着时间的推移,越来越多的接口和方法被介绍了。最终的结果可能是数量众多的接口和方法,它们各不相同。开发者必须小心地学习了解每一种以便可以正确地使用这些接口。这既费时又容易出错。

REST的建筑风格最早是在2000推出的,主要是为配合HTTP / 1.1工作设计的。它的核心原则是定义命名资源,那样就可以使用少量的方法进行操作。资源和方法被称为API的名词和动词。用HTTP协议,将资源名称自然映射到URL,这样一来方法自然地映射到HTTP的获取、放置、修补和删除方法上。

在网络中,HTTP REST API 最近已经非常成功。在2010年, 大概74%的公共网络API属于HTTP REST API(或类REST API)。

虽然HTTP REST API在Internet上非常流行,但它们承载的流量比传统RPC API小。例如,在美国,大约有一半在高峰时间的互联网流量是视频内容,考虑到性能原因很少有人会考虑使用REST API提供这些内容。在内部数据中心中,许多公司使用基于套接字的RPC API来承载大部分网络流量,这可以比公共REST API高出一个数量级。

事实上,由于各种原因,RPC API和HTTP REST API都需要。理想的情况下,API平台应该为所有API提供最好的支持。这个设计指南帮助你设计和构建出符合此原则的API。它通过将面向资源的设计原则应用于通用API设计,同时定义了许多通用的设计模式,以提高可用性和减少复杂性。

注意:本设计指南解释了如何将REST原则应用于与编程语言、操作系统或网络协议无关的API设计中。它不是指导创建REST API的指南。


什么是REST API?

REST API被建模为单独可寻址资源的集合(API的名词)。资源可通过它们的资源名称来引用,并通过一组方法(也称为动词或操作)进行操作。
谷歌API(也称为REST方法)的标准方法是列表(List), 获取(Get), 创建(Create), 更新(Update), 以及删除(Delete)。自定义方法(也称为自定义谓词或自定义操作)也可用于为那些不容易映射到一个标准的方法的功能的API设计器,如数据库事务。

注意:自定义动词并不意味着创建自定义HTTP谓词以支持自定义方法。对于基于HTTP的API,它们只映射到最合适的HTTP谓词。

设计流程

设计指南建议在设计面向资源的API时采取以下步骤(更多细节包括在以下部分):

  • 确定API提供的资源类型。
  • 确定资源之间的关系。
  • 根据类型和关系决定资源名称方案。
  • 决定资源模式。
  • 为资源附加最少的方法集。

资源

一个面向资源的API通常被建模为资源层次结构,这些层次结构要么是一个简单的资源要么就是一个资源的集合。为了方便,它们通常分别被称为一个资源和一个集合。

  • 一个集合包含一个相同类型的资源的列表。例如,一个用户有一个联系人列表。
  • 一个资源有一些状态以及零或多个子资源。每个子资源可以是一个简单的资源或者一个资源集合。

例如,Gmail API有一个用户集合,每个用户拥有一个消息集合、一个线程集合、一个标签集合、一个配置文件资源和多个设置资源。

虽然存储系统和REST API之间有一些概念上的一致性,一个拥有面向资源API的服务不一定是个数据库,同时它在解释资源和方法方面有巨大的灵活性。例如,创建日历事件(资源)可以为与会者创建附加事件,向与会者发送电子邮件邀请,保留会议室,并更新视频会议日程。


方法

面向资源的API的主要特点是它强调资源(数据模型)在资源(功能)上执行的方法。一个典型的面向资源API会用少量的方法公开大量资源。这些方法可以是标准方法,也可以是自定义方法。对于本指南,标准方法是:列表(List)、获取(Get)、创建(Create)、更新(Update)和删除(Delete)。

API函数自然地映射到标准方法之一,该方法应该在API设计中使用。对于不能够自然地映射到标准方法之一的功能,可以使用自定义方法。自定义方法提供了与传统RPC API相同的设计自由度,可用于实现通用的编程模式,如数据库事务或数据分析。


例子

下面的章节介绍了一些关于如何将面向资源的API设计应用到大规模服务的真实世界的例子。

Gmail API

Gmail API服务实现了Gmail API并公开了大部分Gmail功能。它具有以下资源模型:

  • Gmail API服务:gmail.googleapis.com
  • 用户集合:users/*。每个用户都有以下资源。
    • 消息的集合:users/*/messages/*
    • 线程集合:users/*/threads/*
    • 标签集合:users/*/threads/*
    • 变化历史的集合:users/*/history/*
    • 表示用户配置文件的资源:users/*/profile
    • 表示用户设置的资源:users/*/settings

Google Cloud 发布(Pub)/订阅(Sub) API

pubsub.googleapis.com实现谷歌云服务的发布/订阅API,它定义了以下资源模型:

  • API服务:pubsub.googleapis.com
  • 主题的集合:projects/*/topics/*
  • 订阅的集合:projects/*/subscriptions/*

注意: 其他发布/订阅API的实现可以选择不同的资源命名方案。

Editor huiquan @denghuiquan
2017-03-23 01:25AM.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.