jenkins 构建api_构建开发人员友好的REST API的最佳实践

jenkins 构建api

REST APIs are probably the simplest way to integrate two applications over the Internet. Most web developers have integrated with or built them.

REST API可能是通过Internet集成两个应用程序的最简单方法。 大多数Web开发人员已经集成或构建了它们。

I’ve written this guide to help developers design and build REST APIs that are easier to integrate with and easier to maintain. It includes tricks that I’ve borrowed from my colleagues, ideas that I learnt from books and articles, and some things from my own experience with REST APIs. So, you may find these best practices a bit opinionated.

我编写了本指南,以帮助开发人员设计和构建更易于集成和维护的REST API。 它包括我从同事那里借来的技巧,从书本和文章中学到的想法,以及从我自己对REST API的经验中学到的一些东西。 因此,您可能会发现这些最佳实践有些自以为是。

This guide starts with REST resources, then looks into requests and responses, then versioning, security, and, finally, developer experience. All practices here are platform- and language-agnostic.

本指南从REST资源开始,然后研究请求和响应,版本控制,安全性以及最终的开发人员体验。 这里的所有实践都与平台和语言无关。

REST API资源 (REST API Resources)

The concept of a “resource” is the cornerstone of REST. It is convenient to think about them as either collections of entities, or individual entities.

“资源”的概念是REST的基石。 将它们视为实体的集合或单个实体是很方便的。

在资源名称中使用名词 (Use Nouns in Resource Names)

When naming REST API resources, use nouns and avoid verbs.

在命名REST API资源时,请使用名词并避免动词。

For example:

例如:

  • /post for the resource that returns a collection of blog posts,

    /post作为返回博客文章集合的资源,

  • /me for the resource that returns the information about the current user.

    /me表示返回有关当前用户信息的资源。

Sometimes a REST API needs to provide functionality that produces some output without actually exposing any entity, such as translation or currency conversion. You can still use nouns in such resource names. For example, /translation for a resource that returns translations from one language to another. Or /amount for the resource that converts amounts between currencies.

有时,REST API需要提供可产生某些输出而又不会实际暴露任何实体的功能,例如转换或货币换算。 您仍可以在此类资源名称中使用名词。 例如, /translation表示将一种语言的翻译返回另一种语言的资源。 或/amount作为用于在货币之间转换金额的资源。

I believe it is always possible to replace a verb in a resource name with a noun. I’ll share a few ways how to achieve that a bit later.

我相信总是可以用名词替换资源名称中的动词。 稍后,我将分享一些实现该目标的方法。

避免深层嵌套的资源 (Avoid Deeply Nested Resources)

Sometimes resources have to be nested. For example, a nested resource that represents blog post comments could be /posts/r83fj3/comments. When working with nested resources, it is best to avoid deep nesting. Two levels like in the example is enough in most scenarios.

有时必须嵌套资源。 例如,表示博客文章评论的嵌套资源可以是/posts/r83fj3/comments 。 使用嵌套资源时,最好避免深度嵌套。 在大多数情况下,示例中的两个级别就足够了。

使用非顺序资源ID (Use Non-Sequential Resource Ids)

It is best to use non-sequential (maybe random) ids with resources. That will protect your data from enumeration attacks and will also make things like merging datasets simpler if you find that two of your resources have to become one while preserving the ids of the entities. UUIDs or random strings are good enough. For example, /posts/r83fj3.

最好对资源使用非顺序(可能是随机)ID。 这将保护您的数据免受枚举攻击,并且如果您发现必须在保留实体ID的同时将其中的两种资源合为一体,则使合并数据集等事情变得更加简单。 UUID或随机字符串就足够了。 例如, /posts/r83fj3

要求 (Requests)

用适当的HTTP动词表示CRUD操作 (Represent CRUD Actions with Appropriate HTTP Verbs)

A typical REST API resource supports create, read, update, and delete operation. Let’s take a look at a canonical way to support that using the /posts resource for managing blog posts.

典型的REST API资源支持创建,读取,更新和删除操作。 让我们看一下使用/posts资源管理博客文章的一种规范方法。

A developer should use these HTTP requests for those operations:

开发人员应将以下HTTP请求用于这些操作:

  • POST example.com/posts/ — to create a new blog post

    POST example.com/posts/创建新的博客文章

  • GET example.com/posts/r83fj3 — to fetch a blog post by its id

    GET example.com/posts/r83fj3通过ID获取博客帖子

  • PATCH example.com/posts/r83fj3 — to update specified properties of a blog post by its id

    PATCH example.com/posts/r83fj3通过其ID更新博客文章的指定属性

  • PUT example.com/posts/r83fj3 — to replace a blog post by its id

    PUT example.com/posts/r83fj3用其ID替换博客文章

  • DELETE example.com/posts/r83fj3 — to delete a blog post by its is

    DELETE example.com/posts/r83fj3按is删除博客文章

Please note the difference between PATCH and PUT requests.

请注意PATCH和PUT请求之间的区别。

避免自定义(非CRUD)操作 (Avoid Custom (Non-CRUD) Actions)

Some resources may need to support actions that don’t map to HTTP verbs well. For example, a blog post may need to be published and unpublished.

某些资源可能需要支持无法很好地映射到HTTP动词的动作。 例如,博客文章可能需要发布未发布

A popular but non-RESTful approach would be to use URLs like:

一种流行但非RESTful的方法是使用类似以下的URL:

  • POST /posts/d92hf73/publish

    POST /posts/d92hf73/publish

  • POST/posts/d92hf73/unpublish

    POST/posts/d92hf73/unpublish

This goes against REST principles because /posts/d92hf73/publish is not a URL for a resource. Let’s look at a few ways how to add support for publishing and un-publishing blog posts in a RESTful way.

这违反了REST原则,因为/posts/d92hf73/publish不是资源的URL。 让我们看一下几种方法,如何以RESTful方式增加对发布和取消发布博客文章的支持。

One RESTful, but not particularly elegant, approach is to use PATCH requests like this:

一种RESTful但不是特别优雅的方法是使用PATCH请求,如下所示:

PATCH example.com/posts/d92hf73 with parameters like { “status”: “published” } or { “status”: “unpublished” }.

使用诸如{ “status”: “published” }{ “status”: “unpublished” }类的参数来PATCH example.com/posts/d92hf73

Another approach is to introduce a nested resource and call it commands or actions, then the request would look like:

另一种方法是引入嵌套资源,并将其称为commandsactions ,然后请求将如下所示:

POST example.com/posts/d92hf73/commands { “name”: “publish” }

POST example.com/posts/d92hf73/commands { “name”: “publish” }

POST example.com/posts/d92hf73/commands { “name”: “unpublish” }

POST example.com/posts/d92hf73/commands { “name”: “unpublish” }

This is a more RESTful and also much more extendable approach as it allows adding more URLs to the API without changing its interface.

这是一种更加RESTful的方法,也是一种更具扩展性的方法,因为它允许在不更改接口的情况下向API添加更多URL。

The third approach is to introduce a nested resource that represents the concept of “publishing”, such as “publication”. I think this is the best option out of these three.

第三种方法是引入表示“发布”概念的嵌套资源,例如“出版物”。 我认为这是这三个中的最佳选择。

  • POST example.com/posts/d92hf73/publication to publish a blog post by creating a publication.

    POST example.com/posts/d92hf73/publication通过创建出版物来发布博客文章。

  • DELETE example.com/posts/d92hf73/publication to un-publish a blog post by deleting a publication.

    DELETE example.com/posts/d92hf73/publication以通过删除出版物来取消发布博客文章。

正确使用HTTP动词 (Use HTTP Verbs Correctly)

According to REST principles, the meaning of a request should be represented with HTTP verbs. Let’s look at their meaning and what actions they express:

根据REST原则,请求的含义应使用HTTP动词表示。 让我们看看它们的含义以及它们表达的动作:

  • POST example.com/posts creates a new resource

    POST example.com/posts创建一个新资源

  • GET example.com/posts/d92hf73 retrieves the resource

    GET example.com/posts/d92hf73检索资源

  • PATCH example.com/posts/d92hf73 updates the specified properties of the resource

    PATCH example.com/posts/d92hf73 更新资源的指定属性

  • PUT example.com/posts/d92hf73 replaces the resource

    PUT example.com/posts/d92hf73 替换了资源

  • DELETE example.com/posts/d92hf73 removes the resource

    DELETE example.com/posts/d92hf73删除资源

  • GET example.com/posts retrieves a collection of resources

    GET example.com/posts检索资源集合

GET requests should be idempotent and they should never change the state of the resource. In addition, GET requests should be cacheable as well for the best performance of API. I’ll talk about caching a bit more below.

GET请求应该是幂等的,并且永远不应更改资源的状态。 另外,GET请求也应该是可缓存的,以实现API的最佳性能。 我将在下面谈论更多缓存。

PUT and DELETE requests should be idempotent as well.

PUTDELETE请求也应该是幂等的。

POST and PATCH are not idempotent — they change the state of the resource.

POSTPATCH不是幂等的,它们会更改资源的状态。

考虑使用ETag标头 (Consider Using ETag Header)

When making UPDATE requests to an API there is a chance that the resource has already been modified and the PUT or PATCH request may overwrite it.

向API发出UPDATE请求时,有可能资源已被修改, PUTPATCH请求可能会覆盖它。

There is a way to catch that case with the ETag header. ETag response HTTP header is an identifier for a specific version of a resource. The value in this header is calculated on the server side for the response and it can be a hash of the resource.

有一种方法可以使用ETag标头来捕获这种情况。 ETag响应HTTP标头是资源特定版本的标识符。 此标头中的值是在服务器端为响应计算的,它可以是资源的哈希。

This value can be sent to the server when the same resource is re-loaded to verify if there is a need to refetch it or when this resource is being updated to verify that the resource hasn’t changed between the time when it was fetched and being sent back.

当重新加载相同的资源以验证是否需要重新获取该资源时,或者在更新该资源以确认从获取资源到获取资源之间,资源是否已更改时,可以将该值发送到服务器。被送回。

In the first case the value is sent back in the If-None-Match request header and if that value is the same as the ETag for the resource, the API can respond with 304 Not Modified with the empty body. This is helpful if the resource is expensive to construct on the server.

在第一种情况下,该值会在If-None-Match请求标头中发回,并且如果该值与资源的ETag相同,则API可以使用空正文响应304 Not Modified 。 如果在服务器上构造资源昂贵,这将很有帮助。

In the second case, the API should check if the ETag value is still the same otherwise return 412 Precondition Failed error response. This allows to catch cases where the resource has been modified before the POST request was received by another request and prevents overwriting the data.

在第二种情况下,API应该检查ETag值是否仍然相同,否则返回412 Precondition Failed错误响应。 这允许捕获在另一个请求接收到POST请求之前修改了资源的情况,并防止覆盖数据。

回应 (Responses)

We’ve talked about resources, requests and verbs. Let’s now look into response structure for successful and failed requests.

我们已经讨论了资源,请求和动词。 现在,让我们研究成功和失败请求的响应结构。

When returning a resource it is best to use simple JSON structure, i.e.:

返回资源时,最好使用简单的JSON结构,即:

{
"id": "d92hf73",
"title": "Best Practices for Public REST APIs",
"body": "Foo bar...",
"createdAt": "2020-08-30 11:17:09 UTC"
}

This is a very simple structure — it only includes attributes to describe the resource. What if we would like to add more information to this JSON object?

这是一个非常简单的结构-它仅包含描述资源的属性。 如果我们想向此JSON对象添加更多信息怎么办?

If you are familiar with the HATEOAS component of REST architecture then you may want to include links to related entities and commands that can be performed on the resource. Let’s say we can publish or delete a post and that a post has comments and an author.

如果您熟悉REST体系结构的HATEOAS组件,则可能需要包括指向相关实体的链接以及可以在资源上执行的命令。 假设我们可以发布或删除帖子,并且该帖子包含评论和作者。

There are two ways to do this:

有两种方法可以做到这一点:

{
"id": "d92hf73",
"title": "Best Practices for Public REST APIs",
"body": "Foo bar...",
"createdAt": "2020-08-30 11:17:09 UTC",
"commentsUrl": "https://example.com/posts/d92hf73/comments",
"authorUrl": "https://example.com/author/f9f3ks0",
"publishUrl": "https://example.com/posts/d92hf73/publication",
"deleteUrl": "https://example.com/posts/d92hf73"
}

Another way is with using an “envelope”:

另一种方法是使用“信封”:

{
"data": {
"id": "d92hf73",
"title": "Best Practices for Public REST APIs",
"body": "Foo bar...",
"createdAt": "2020-08-30 11:17:09 UTC"
},
"links": {
"commentsUrl": "https://example.com/posts/d92hf73/comments",
"authorUrl": "https://example.com/author/f9f3ks0",
"publishUrl": "https://example.com/posts/d92hf73/publication",
"deleteUrl": "https://example.com/posts/d92hf73"
}
}

The first option looks a bit cleaner to me because it doesn’t introduce extra nesting and structure unrelated to the resource.

第一种选择对我来说看起来更干净一些,因为它没有引入与资源无关的额外嵌套和结构。

Including links in responses allows the API client developers to avoid constructing URLs in their code. That also allows API developers to change the URLs without breaking API clients. At least the ones that have been relying on the links that the API returns.

在响应中包含链接可以使API客户端开发人员避免在其代码中构造URL。 这也允许API开发人员在不破坏API客户端的情况下更改URL。 至少那些一直依赖于API返回的链接的链接。

Another interesting practice is to include the type of the resource in the response and the link to itself. In this case the response may look like:

另一个有趣的做法是在响应中包括资源的类型及其自身的链接。 在这种情况下,响应可能类似于:

{
"id": "d92hf73",
"self": "https://example.com/posts/d92hf73",
"type": "Post",
"title": "Best Practices for Public REST APIs",
"body": "Foo bar...",
"createdAt": "2020-08-30 11:17:09 UTC",
"commentsUrl": "https://example.com/posts/d92hf73/comments",
"authorUrl": "https://example.com/author/f9f3ks0",
"publishUrl": "https://example.com/posts/d92hf73/publication",
"deleteUrl": "https://example.com/posts/d92hf73"
}

The case for keys in the response JSON should probably always be the camelCase. As it is standard for Javascript and JSON comes from the Javascript world.

响应JSON中的键的大小写应该始终是camelCase。 由于它是Javascript和JSON的标准,因此它来自Javascript世界。

集合回应 (Collection Responses)

Collection responses may use an envelope to wrap the collection items. Here is an example, where blog posts are returned under the data key. The links key in this example contains URLs that point to the next and the previous pages with posts.

收集响应可以使用信封来包装收集项目。 这是一个示例,其中博客帖子在data键下返回。 本示例中的links键包含指向带有帖子的下一页和上一页的URL。

GET example.com/api/posts?page=2&limit=10

GET example.com/api/posts?page=2&limit=10

{
"data": [{
"id": "d92hf73",
"title": "Best Practices for Public REST APIs"
}, {
"id": "hwp8a2j",
"title": "REST vs GraphQL"
}],
"links": {
"nextUrl": "d92hf73",
"prevUrl": "example.com/posts"
}
}

Collection responses don’t have to use an envelope. In this case the API can return the pagination URLs in HTTP response headers like in this example:

收集回复不必使用信封。 在这种情况下,API可以在HTTP响应标头中返回分页URL,如下例所示:

GET example.com/api/posts?page=2&limit=10

GET example.com/api/posts?page=2&limit=10

[
{
"id": "d92hf73",
"title": "Best Practices for Public REST APIs"
},
{
"id": "hwp8a2j",
"title": "REST vs GraphQL"
}
]

HTTP response header:

HTTP响应标头:

Link: <https://example.com/api/posts?page=1>; rel=”prev”, <https://example.com/api/posts?page=3>; rel=”next”, <https://example.com/api/posts?page=34>; rel=”last”, <https://example.com/api/posts>; rel=”first”

Link: <https://example.com/api/posts?page=1>; rel=”prev”, <https://example.com/api/posts?page=3>; rel=”next”, <https://example.com/api/posts?page=34>; rel=”last”, <https://example.com/api/posts>; rel=”first”

考虑使用JSON:API (Consider Using JSON:API)

If you’d rather use an existing standard for formatting responses in your API, then you may want to use JSON:API. It is relatively popular and provides more or less standard response structure. On the other hand, it is rather verbose and may be time-consuming to maintain.

如果您希望使用现有标准来格式化API中的响应,那么您可能需要使用JSON:API。 它相对流行,并提供或多或少的标准响应结构。 另一方面,它很冗长,维护可能很耗时。

See: https://jsonapi.org/

请参阅: https//jsonapi.org/

对空响应使用有意义的HTTP响应代码 (Use Meaningful HTTP Response Codes with Empty Responses)

POST requests to create a resource may return no content and instead use 201 Created HTTP status and set Location HTTP response header to tell the API client how to retrieve the resource.

创建资源的POST请求可能不返回任何内容,而是使用201 Created HTTP状态并设置Location HTTP响应标头来告诉API客户端如何检索资源。

In some APIs POST, PATCH, PUT requests may return no data because request processing is done asynchronously. In this case the request may return 202 Accepted HTTP status to indicate that the request has been queued for processing.

在某些API POSTPATCHPUT请求中可能不返回任何数据,因为请求处理是异步完成的。 在这种情况下,请求可以返回202 Accepted HTTP状态,以指示请求已排队等待处理。

When POST, PATCH, PUT, DELETE requests don’t semantically need to return any response, they should respond with 204 No content HTTP response status.

POSTPATCHPUTDELETE请求在语义上不需要返回任何响应时,它们应使用204 No content HTTP响应状态进行响应。

使用丰富的错误响应 (Use Rich Error Responses)

Error responses should not only represent error information but also use correct HTTP status codes. If the data sent by the API client caused an error then the code should be one of 4xx codes. If the error was caused by an issue on the server side that should be one of 5xx codes.

错误响应不仅应表示错误信息,而且应使用正确的HTTP状态代码。 如果API客户端发送的数据导致错误,则该代码应为4xx代码之一。 如果错误是由服务器端的问题引起的,则应为5xx代码之一。

Error responses should contain sufficient information to describe the error for the API client, the API client developer and in some cases for the API client user. An error response may look like this:

错误响应应包含足够的信息来描述API客户端,API客户端开发人员以及在某些情况下针对API客户端用户的错误。 错误响应可能如下所示:

POST example.com/api/posts

POST example.com/api/posts

{
"errorCode": 123,
"errorMessage": "Blog post title is too long",
"developerMessage": "title cannot be longer than 255 characters",
"info": "https://docs.example.com/api/errors/123"
}

Sometimes many errors may occur when handling an API request, for example, when validating the data sent in the POST request body. An error response may look like this in that case:

有时在处理API请求时可能会发生许多错误,例如,验证POST请求正文中发送的数据时。 在这种情况下,错误响应可能如下所示:

POST example.com/api/posts

POST example.com/api/posts

[
{
"errorCode": 123,
"errorType": "validationError",
"errorMessage": "Blog post title is too long",
"developerMessage": "title cannot be longer than 255 characters",
"info": "https://docs.example.com/api/errors/123"
},
{
"errorCode": 123,
"errorType": "validationError",
"errorMessage": "Blog post body is too short",
"developerMessage": "body cannot be empty",
"info": "https://docs.example.com/api/errors/123"
}
]

API developers usually start with error responses like this:

API开发人员通常从以下错误响应开始:

POST example.com/api/posts

POST example.com/api/posts

Error message here.

Error message here.

But later they migrate to { "error": "Error message here" } and then maybe [{ "error": "Error message here" }, { "error": "Another error message here" }]. So it may be a good idea to support several errors in a response from the very beginning.

但是后来他们迁移到{ "error": "Error message here" } ,然后可能迁移到[{ "error": "Error message here" }, { "error": "Another error message here" }] 。 因此,从一开始就在响应中支持多个错误可能是一个好主意。

API版本控制 (API Versioning)

It is best to design and build the REST API in a way that doesn’t require versioning. In other words, API developers should avoid breaking changes at all costs. If you have to introduce large scale breaking changes, then you’re publishing a new API. If you have to change a specific resource so much that it becomes incompatible with its current version, maybe that should be a new resource?

最好以不需要版本控制的方式设计和构建REST API。 换句话说,API开发人员应避免不惜一切代价打破变更。 如果您必须进行大规模的重大更改,那么您将发布一个新的API。 如果必须对特定资源进行大量更改以使其与当前版本不兼容,那么也许应该是新资源?

If you, however, decided to introduce versioning here are two strategies for that:

但是,如果您决定引入版本控制,这里有两种策略:

  • version as part of the URL,

    版本作为网址的一部分,
  • version in a request header.

    请求标头中的版本。

版本作为URL的一部分 (Version as Part of URL)

Versions can be specified:

可以指定版本:

  • at the domain level, i.e. api2.example.com/posts . The advantage is that the versions are as “far” from each other as possible and two versions can be implemented completely differently. This approach is the closest to having API no versioning at all. A nice thing from the REST perspective is that the URLs of resources remain “pure”, they don’t need to contain any fragments like “v1”. They only point at resources.

    在域级别 ,即api2.example.com/posts 。 优点是版本之间的距离尽可能远,并且两个版本可以完全不同地实现。 这种方法最接近于根本没有API版本化。 从REST角度来看,一件好事是资源的URL保持“纯”,它们不需要包含任何片段,例如“ v1”。 他们只指向资源。

  • as a path fragment, i.e. example.com/api/v3/posts . The advantages of this approach are similar to the previous one, but the URL doesn’t look particularly “pure”. But that’s not always an issue from a pragmatic point of view.

    作为路径片段 ,例如example.com/api/v3/posts 。 这种方法的优势与前一种类似,但是URL看起来并不是特别“纯净”。 但是从务实的角度来看,这并不总是一个问题。

  • as a request parameter, i.e. example.com/api/posts?version=3 . The advantage is that without the explicitly specified version, API developers can choose to automatically fall back to the latest or the oldest supported version. On the one hand, migrations will happen “automatically”, on the other, that may break API clients if API developers introduce breaking changes.

    作为请求参数 ,即example.com/api/posts?version=3 。 优点是,没有明确指定的版本,API开发人员可以选择自动回退到受支持的最新或最早的版本。 一方面,迁移将“自动”进行,另一方面,如果API开发人员引入了重大更改,则迁移可能会破坏API客户端。

请求标头中的版本 (Version in a Request Header)

The API client can also specify the required API version using:

API客户端还可以使用以下命令指定所需的API版本:

  • a custom HTTP request headers like Accepts-version: 23, Accepts-version: 23

    自定义HTTP请求标头,例如Accepts-version: 23Accepts-version: 23

  • a standard request header, such as Accept: application/vnd.example.v23+json or Accept: application/json; version=23

    标准请求标头 ,例如Accept: application/vnd.example.v23+jsonAccept: application/json; version=23 Accept: application/json; version=23

If API is using caching, it is important to ensure the value of that request header is taken into account when caching a response.

如果API使用缓存,则确保在缓存响应时考虑到该请求标头的值,这一点很重要。

仅使用主要版本号 (Use Only Major Version Numbers)

Use only major version numbers, like v11, don’t use minor versions, such as v2.2.

仅使用主要版本号(例如v11),而不使用次要版本号(例如v2.2)。

如果未指定版本,请使用最新版本 (Use the Latest Version If No Version Specified)

If no version is specified, use the latest one because that will prompt the API client developers to specify the desired version if they see errors when their API clients are making calls. With the oldest version used by default there is no way to automatically tell API client developers that a new version is available.

如果未指定任何版本,请使用最新版本,因为这将提示API客户端开发人员在API客户端进行调用时发现错误时指定所需的版本。 默认情况下使用最旧的版本,因此无法自动告诉API客户端开发人员新版本可用。

在所有API资源上使用一致的版本。 (Use consistent versions across all API resources.)

I.e. /posts and /me resources for a blog API should always have the same supported versions even though only some of the resources may have changed between the versions.

即,博客API的/posts/me资源应始终具有相同的受支持版本,即使在某些版本之间可能仅更改了一些资源。

使用日落响应标头传达资源报废 (Use Sunset Response Header to Communicate Resource End-of-Life)

Use Sunset response header to indicate that a version of a resource is going to be deprecated. Another approach is to randomly return 410 Gone HTTP response code but that may unexpectedly break some clients.

使用Sunset响应标头指示将不赞成使用资源的版本。 另一种方法是随机返回410 Gone HTTP响应代码,但这可能会意外中断某些客户端。

认证方式 (Authentication)

Best practice is to use OAuth2. It is widely used and many developers are familiar with it. Do not invent your own authentication mechanism. With OAuth you’ll be able to disable a specific client from accessing your API and specific apps as well.

最佳做法是使用OAuth2。 它被广泛使用,并且许多开发人员都熟悉它。 不要发明自己的身份验证机制。 使用OAuth,您还可以禁止特定的客户端访问您的API和特定的应用程序。

There might be cases though when you may allow API clients to use access tokens. In that case the API should allow many tokens per user. Otherwise, it will be impossible to the customers to roll their tokens without any interruption/downtime.

但是,在某些情况下,您可能允许API客户端使用访问令牌。 在这种情况下,API应该允许每个用户使用许多令牌。 否则,客户将不可能在没有任何中断/停机的情况下滚动其令牌。

API安全性 (API Security)

All API traffic should be sent over HTTPS obviously so it could be encrypted in transit.

显然,所有API流量都应通过HTTPS发送,以便可以在传输过程中对其进行加密。

使用率限制和限制 (Use Rate Limiting & Throttling)

It is important to use request rate-limiting per API client to detect clients that make too many requests and can take the API service down.

使用每个API客户端的请求速率限制来检测发出过多请求并可能导致API服务中断的客户端非常重要。

An API should support 429 response code and headings like Retry-After to provide info when a request should be retried. It is also great to support headers like X-RateLimit-Limit, X-RateLimit-Remainingand X-RateLimit-Reset. Hopefully, the RateLimit-* headers will become standard soon.

API应该支持429个响应代码和诸如Retry-After类的标题,以在重试请求时提供信息。 支持标头,例如X-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-Reset也很棒。 希望RateLimit-*标头将很快成为标准。

考虑每日或每月配额的请求数 (Consider Daily or Monthly Quotas for the Number of Requests)

An API should have quotas on the number of requests per month or day for each API client. That allows to control access to the API for individual clients and to prevent using too many computing resources for serving requests.

一个API应该对每个API客户端每月或每天的请求数量有配额。 这样可以控制单个客户端对API的访问,并防止使用过多的计算资源来处理请求。

It is best to not try implementing rate limiting and quotas yourself and use a third-party API gateway product.

最好不要尝试自己实施速率限制和配额,而要使用第三方API网关产品。

开发人员经验 (Developer Experience)

APIs are built for other developers to use. So API developers should make it easy for the client developers to start using their APIs.

API是供其他开发人员使用的。 因此,API开发人员应该使客户端开发人员可以轻松地开始使用其API。

保持一致性 (Maintain Consistency)

Everything in the API needs to be consistent: naming, error representation, ids, error codes, status codes, headers, everything should be predictable.

API中的所有内容都必须保持一致:命名,错误表示,ID,错误代码,状态代码,标头,所有内容都应该是可预测的。

提供质量开发人员文档 (Provide Quality Developer Documentation)

Documentation, examples, client libraries in popular languages should be available as freely as possible. It is very odd to see an API that requires developers to register to access documentation.

应尽可能免费提供流行语言的文档,示例和客户端库。 看到要求开发人员注册才能访问文档的API是很奇怪的。

Documentation should describe the API at a high level, explain what each resource is, list supported requests as well as successful responses and errors. Each type of output that API produces should be documented and should have realistically looking examples.

文档应该在较高级别上描述API,解释每种资源是什么,列出支持的请求以及成功的响应和错误。 API产生的每种类型的输出都应记录在案,并应具有逼真的示例。

Make sure your API docs are up to date. Ideally, you should be able to generate them from the API source code.

确保您的API文档是最新的。 理想情况下,您应该能够从API源代码生成它们。

The onboarding process should be super fast and easy for developers to start using your API. Maybe you can introduce interactive documentation, or write a quick-start guide, or record a video walk-through?

入门过程应该非常快速,并且使开发人员可以轻松使用您的API。 也许您可以介绍交互式文档,或编写快速入门指南,或录制视频演练?

为API客户端开发人员提供支持 (Provide Support for API Client Developers)

Developers will likely use various languages when working with your API so it would be fantastic to provide them with examples of using your API in different languages.

开发人员在使用您的API时可能会使用多种语言,因此很高兴向他们提供使用不同语言使用API​​的示例。

What would be even better is to provide them with open source libraries hosted on GitHub that they could use in their projects.

更好的办法是为他们提供托管在GitHub上的开源库,供他们在项目中使用。

It is a good idea to monitor those GitHub repos to see if developers open PRs or issues.

监视那些GitHub仓库以查看开发人员是否打开PR或问题是一个好主意。

It is also a good idea to monitor Q&A sites like Stack Overflow to see if people are asking questions about your API. A support email address for client developers to contact the API developers might be very helpful.

监视诸如Stack Overflow之类的问答网站也是一个好主意,以查看是否有人在询问有关您的API的问题。 客户开发人员与API开发人员联系的支持电子邮件地址可能会很有帮助。

If you can create a developer community on GitHub, or Stack Overflow, or on your own website around your API that will be fantastic and will also allow API client developers to support each other.

如果您可以在GitHub或Stack Overflow上或在您自己的API周围的网站上创建开发人员社区,那将是很棒的选择,并且还允许API客户端开发人员相互支持。

考虑提供开发人员工具 (Consider Providing Developer Tools)

Consider providing insights for your API users into how they use your API: what requests they make, how many successful and failed ones they got, how close they are to reaching the limits of the current plan. It is not applicable to every API probably, but for some that might be very useful for debugging purposes.

考虑为您的API用户提供有关他们如何使用您的API的见解:他们提出了哪些请求,他们获得了多少成功和失败的请求,与达到当前计划的极限有多接近。 它可能不适用于每个API,但对于某些可能对于调试目的非常有用的API。

That’s pretty much it. We’ve talked about best practices for designing resources and requests, successful and error responses, versioning, API security, and developer experience. I hope you have found this little guide useful and will be able to apply them when designing and building your next REST API.

就是这样。 我们已经讨论了设计资源和请求,成功和错误响应,版本控制,API安全性和开发人员经验的最佳实践。 希望本指南对您有所帮助,并且可以在设计和构建下一个REST API时应用它们。

This guide is based on my talk at Melbourne API Meetup in November 2019. You can find the slides here.

该指南是基于我在墨尔本API聚会谈话在2019年十一月,您可以找到幻灯片这里

翻译自: https://levelup.gitconnected.com/best-practices-for-building-developer-friendly-rest-apis-e6a419fcbd38

jenkins 构建api

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值