openapi

Some API developers use API descriptions to plan the interface of an API before building it, which is known as the “API design first” workflow. Others build the API then generate (or manually produce) API descriptions later, which is the “code-first” workflow. We wrote API Design-first vs Code-first recently to help get you up to speed on the differences, but how do you actually create these API descriptions?

一些API开发人员在构建API之前会使用API​​描述来计划API接口,这被称为“ API设计优先”工作流。 其他人会构建API,然后稍后生成(或手动生成)API描述,这就是“代码优先”的工作流程。 我们最近写了API Design First和Code First,以帮助您快速了解差异,但是您如何实际创建这些API描述?

Many of these API descriptions (OpenAPI, JSON Schema, or GraphQL Schemas) involve writing out a bunch of special keywords in YAML, JSON, or another text language. Neither the design-first or code-first crew enjoy writing thousands of lines of that by hand. Why? Well, say you’ve got a list of integers:

这些API描述( OpenAPIJSON SchemaGraphQL Schemas )中的许多描述都涉及用YAML,JSON或其他文本语言编写一堆特殊关键字。 设计优先或代码优先的工作人员都不喜欢手工编写数千行代码。 为什么? 好吧,假设您有一个整数列表:

schema:
type: array
description: List of IDs
items:
type: integer
description: Pet ID

Designing an API with 100 endpoints like that will get you through at least one keyboard (maybe two if it’s a Macbook). Designing a few APIs could drive you bonkers.

设计具有100个端点的API,将使您至少通过一个键盘(如果是Macbook,则可能需要两个)。 设计一些API可能会助您一臂之力。

Let’s look at some alternatives to hand-rolling your own homegrown artisanal YAML, and how these approaches fit into design-first or code-first. More importantly, let’s see how they can be used to achieve the ultimate goal for API designers: one source of truth for API descriptions that power mocks, documentation, request validation, shareable design libraries, and more.

让我们看看手动滚动自己的本地手工YAML的一些替代方法,以及这些方法如何适合设计优先或代码优先。 更重要的是,让我们看看如何使用它们来实现API设计人员的最终目标:API描述的真相之一,该描述提供了模拟,文档,请求验证,可共享的设计库等等。

注解 (Annotations)

Some programming languages support a syntax-level feature called “Annotations”, for example Java Annotations. An OpenAPI annotation framework provides a bunch of keywords that help the API developer describe the interface of the HTTP request and response, and hopefully it’s telling the truth.

一些编程语言支持称为“注释”的语法级别的功能,例如Java Annotations 。 OpenAPI注释框架提供了一堆关键字,这些关键字可以帮助API开发人员描述HTTP请求和响应的接口,并希望它能说明事实。

class UserController {
@OpenApi(
path = "/users",
method = HttpMethod.POST,
// ...
)
public static void createUser(Context ctx) {
// ...
}
}

Some languages do not have any support for annotations, and they achieve this with docblock comments.

某些语言不支持注释,它们使用docblock注释来实现。

/**
* @OA\Get(path="/2.0/users/{username}",
* operationId="getUserByName",
* @OA\Parameter(name="username",
* in="path",
* required=true,
* description=Explaining all about the username parameter
* @OA\Schema(type="string")
* ),
* @OA\Response(response="200",
* description="The User",
* @OA\JsonContent(ref="#/components/schemas/user"),
* @OA\Link(link="userRepositories", ref="#/components/links/UserRepositories")
* )
* )
*/
public function getUserByName($username, $newparam)
{
// implementation logic ...
}

In JavaScript it looks a bit like this:

在JavaScript中,它看起来像这样:

/**
* @swagger
* /users:
* get:
* description: Returns users
* produces:
* - application/json
* responses:
* 200:
* description: users
* schema:
* type: array
* items:
* $ref: '#/definitions/User'
*/
app.get('/users', (req, res) => {
// implementation logic ...
});

This approach is the oldest around, and is primarily used by the code-first people. It’s easy to understand why: you wrote the code already, so now lets get some docs! Sprinkle some keywords around the code, and the annotation system will integrate with your framework to emit a /docs endpoint, and boom, you've got some documentation. Great, if all you want is documentation.

这种方法是最古老的方法,并且主要由代码优先人员使用。 原因很容易理解:您已经编写了代码,现在让我们获取一些文档! 在代码周围添加一些关键字,注释系统将与您的框架集成以发出/docs端点,并且繁荣,您已经获得了一些文档。 太好了,如果您想要的只是文档。

Design-first people also sometimes use this approach. They design the entire API (writing YAML by hand or with one of the other approaches we’re going to mention), then use Server Generators like openapi-generator or swagger-generator to create their API code. This API code is created from the machine-readable documents that were made in the design process, and the code that is generated is chock full of annotations already, which in turn can generate documentation. Throw those machine-readable documents away, the annotated code is the source of truth now… right?

设计优先的人有时也使用这种方法。 他们设计了整个API(手动编写YAML或使用我们将要提到的其他方法之一编写),然后使用服务器生成器(如openapi-generatorswagger-generator)来创建其API代码。 该API代码是根据设计过程中生成的机器可读文档创建的,并且所生成的代码已经充满了注释,从而可以生成文档。 扔掉那些机器可读的文档,带注释的代码现在就是真理的源头了吧?

One downside to annotations is that they don’t confirm the code is doing what it says. I’ve heard the argument “Annotations are closer to the code they describe, so developers are more likely to keep it up to date”. Do not confuse proximity with accuracy. Developers can forget to make the changes, and developers can make mistakes.

注释的缺点之一是它们不能确认代码是否按照其说明进行操作。 我听说过这样的论点:“注释更接近于它们描述的代码,因此开发人员更可能使它保持最新”。 不要将接近度与精度混淆。 开发人员可以忘记进行更改,而开发人员可以犯错误。

Annotation users need to find a way to contract test the actual output against these annotations, which we’ve written about before in Keeping Documentation Honest.

批注用户需要找到一种方法来对照这些批注对实际输出进行测试,这是我们之前在保持文档诚实中所写的。

The tools in this article generally involve the machine-readable OpenAPI / JSON Schema files around, so you need to export them back to a machine-readable format in order to compare them to the code… This means running a command in the command line which pulls the annotations out into a machine-readable file, then running a tool like Dredd or a JSON Schema validators, which is a pretty awkward step.

本文中的工具通常涉及机器可读的OpenAPI / JSON Schema文件,因此您需要将它们导出回机器可读的格式,以便将它们与代码进行比较……这意味着在命令行中运行命令将注释拉出到机器可读文件中,然后运行Dredd或JSON Schema验证器之类的工具,这是一个非常尴尬的步骤。

Design-first is incompatible with all this, unless you chose to design the API, then generate code with annotations, then figure out how to keep the code, the annotations AND the machine readable designs up to date. If there’s anything worse than two sources of truth it’s three…

除非您选择设计API,然后生成带有注释的代码,然后弄清楚如何使代码,注释和机器可读的设计保持最新状态,否则“设计优先”与所有这些都不兼容。 如果有什么比两个真理来源更糟糕的话,那就是三个……

For this reason, folks who like design-first run and hide from annotations, but the folks who like annotations generally really really love them because to them their code is the source of truth and if they can crowbar one of these test suites in to confirm that then they’re perfectly happy. This mindset can lead to API clients being a bit of an afterthought, but that’s another topic for another article.

因此,喜欢设计优先的人会躲避注释,但是喜欢注释的人通常真的很喜欢它们,因为对他们而言,他们的代码是真理的源泉,如果他们可以撬开这些测试套件中的一个来确认那他们就会很高兴。 这种心态可能会导致API客户端有点事后思考,但这是另一篇文章的另一主题。

DSL(域特定语言) (DSL (Domain Specific Language))

A few DSLs popped up over the years, created by people who wanted to create API Descriptions, but didn’t fancy writing it out in that specific format, with articles like Making OpenAPI / Swagger Bearable With Your Own DSL.

多年来,出现了一些DSL,这些DSL是由想要创建API说明的人创建的,但他们并不希望以特定的格式将其写出来,例如使OpenAPI / Swagger可以支持您自己的DSL

DSL’s can be used in code-first or design-first. You have your code, you have your DSL-based descriptions, and whatever format they were written in doesn’t make much difference here.

DSL可以以代码优先或设计优先的方式使用。 您有了代码,有了基于DSL的描述,无论采用哪种格式编写,在这里都没有多大区别。

;;; ENTITIES
(define pet-entity
(entity "Pet"
'race (string "What kind of dog / cat this is (labrador, golden retriever, siamese, etc...)" "Labrador")
'origin (string "Country of origin" "Egypt")
'birthday (datetime "Birth date of the pet" "2017-10-20T00:14:02+0000")
'species (string "What kind of animal is this" "dog" #:enum '("dog" "cat"))))
(define $pet (schema-reference 'Pet pet-entity))
;;; RESPONSES
(define list-pets-response (jsonapi-paginated-response "List of pets" ($pet)))
;;; REQUESTS
(define pet-request (json-request "Pet Request Body" ($pet)))
;;; MAIN DOC
(define swagger
(my-service-api-doc "Pet Store" "Per store pets management"
(path "/pets") (endpoint-group
'tags pet-tags
'parameters (list store-id-param)
'get (endpoint
'operationId "listPets"
'summary "Retrieve all the pets for this store"
'parameters pagination-params
'responses (with-standard-get-responses 200 list-pets-response))
'post (endpoint
'operationId "createPet"
'summary "Create a new Pet record"
'requestBody pet-request
'parameters (list xsrf-token)
'responses (with-standard-post-responses 200 single-pet-response)))

This is shorter than the OpenAPI YAML it replaces, but it’s also another format for people to learn. People who know how to write up OpenAPI will need to learn this format, and the folks familiar with a different DSL will have to learn this format too. Your editor will also need to learn about this format if you want autocomplete, syntax highlighting, linting and validation. The “native” description formats all have this, but these DSLs usually do not.

它比它所替代的OpenAPI YAML短,但是它也是人们学习的另一种格式。 知道如何编写OpenAPI的人将需要学习这种格式,而熟悉其他DSL的人们也必须学习这种格式。 如果您想要自动完成,语法高亮显示,掉毛和验证,您的编辑器还将需要了解这种格式。 “本机”描述格式都具有此功能,但这些DSL通常没有。

This approach, just like annotations, do not help you ensure that what you’re writing in the DSL is actually correct. The contract written down in the description could be completely incorrect. Some DSLs like RSwag aim to solve this by having their DSL be written as integration texts. The source of truth for how you create OpenAPI is literally integration tests:

就像注释一样,这种方法也无法帮助您确保您在DSL中编写的内容实际上是正确的。 描述中写下的合同可能是完全错误的。 诸如RSwag之类的某些DSL旨在通过将其DSL编写为集成文本来解决此问题。 关于如何创建OpenAPI的真相在于字面上的集成测试:

describe 'Blogs API' do
path '/blogs/{id}' do
get 'Retrieves a blog' do
tags 'Blogs'
produces 'application/json', 'application/xml'
parameter name: :id, :in => :path, :type => :string
response '200', 'blog found' do
schema type: :object,
properties: {
id: { type: :integer },
title: { type: :string },
content: { type: :string }
},
required: [ 'id', 'title', 'content' ]
let(:id) { Blog.create(title: 'foo', content: 'bar').id }
run_test!
end
end
end
end

This approach is pretty handy for Test-driven development (TDD) advocates, but you’re just writing OpenAPI in another form which isn’t particularly any shorter, just more Ruby-ish. RSwag was a big favourite at my last job, but it’s had a rough time getting updated onto OpenAPI v3.0 (still a work in progress 3 years after OpenAPI v3.0 was released).

对于测试驱动开发(TDD)的拥护者来说,这种方法非常方便,但是您只是以另一种形式编写了OpenAPI,这种形式并不是特别简短,只是更像Ruby。 在我上一份工作中,RSwag一直是我的最爱,但是在OpenAPI v3.0上进行更新已经很艰难了(OpenAPI v3.0发布三年后仍在进行中)。

Writing in a DSL or annotations means you’re at the mercy of that maintainer to support functionality that you could already use if you could just… edit the OpenAPI yourself.

编写DSL或注释意味着您只能依靠维护者来支持如果您可以…自己编辑OpenAPI便可以使用的功能。

图形设计编辑 (Graphical Design Editors)

What is the alternative to editing the files but now having to wrangle YAML? Visual thinkers and non-technical people might want a wizard mode, the ability to create arrays of objects with a few buttons, and selection boxes for shared models without having to think about the filepath. Graphical design editors are pretty new in the world of OpenAPI and GraphQL, with a few popping up over the last year or two.

除了编辑文件但现在不得不纠缠YAML之外,还有什么选择? 视觉思想家和非技术人员可能需要向导模式,具有几个按钮的对象阵列创建能力以及共享模型的选择框,而无需考虑文件路径。 图形设计编辑器在OpenAPI和GraphQL领域是相当新的,在过去的一两年中出现了一些。

Two years ago I was looking around for a beautiful, effective graphical editor to satisfy some code-first sticklers pushing back against API design-first at WeWork. I figured a GUI would help them convert, and Stoplight told me they were planning a new GUI. Shortly after seeing their amazing prototype I joined the company to help roll it out to even more folks, and now my job is gathering feedback from the API community to make Studio, our open-source tools, and the new SaaS platform even better. 🥳

两年前,我一直在寻找一个美观,有效的图形编辑器,以满足WeWork上一些反对代码编写优先而不是API设计优先的问题 。 我认为GUI可以帮助他们进行转换,Stoplight告诉我他们正在计划新的GUI。 在看到他们惊人的原型后不久,我加入了该公司,以帮助将其推广到更多人。现在,我的工作是收集API社区的反馈意见,以使Studio ,我们的开源工具和新的SaaS平台更好。 🥳

Modern GUI editors have mocks and docs publishing built right in so you no longer have to figure out your own “DocOps”. Editors like Stoplight Studio add “Design Libraries”, where you can manage shared models between multiple APIs in an organization. These editors support organization-wide style guides to have the editor lint during editing (and/or in continuous integration) to enforce consistency, and a bajillion other things.

现代的GUI编辑器内置了模拟和文档发布功能,因此您不再需要弄清楚自己的“ DocOps”。 Stoplight Studio等编辑器添加了“设计库”,您可以在其中管理组织中多个API之间的共享模型。 这些编辑器支持组织范围的样式指南,以使编辑器在编辑过程中(和/或在连续集成过程中)起绒,以增强一致性,还有不计其数的其他事情。

Image for post
Stoplight Studio with Spectral linting的 Spectral linting results from a custom rule written to stop folks designing a GET endpoint with a body. Stoplight Studio来自于编写自定义规则的结果,该规则用于阻止人们使用主体设计GET端点。

There are a bunch of different OpenAPI-based graphical editors around, check out our list on OpenAPI.Tools:

周围有很多不同的基于OpenAPI的图形编辑器,请查看我们在OpenAPI.Tools上的列表:

GraphQL fans, who are having a lot of the same conversations right now, can check out these:

GraphQL粉丝现在正在进行很多相同的对话 ,可以查看以下内容:

Some editors will help you with part of the API design life-cycle, but make a lot of difficult assumptions about what order you’re going to do what in. They might help you create a design, then they’d assume you wanted to export it and generate some code, leaving your machine-readable description documents floating around to become obsolete, and giving you no way to edit them even if you wanted to. Other tools let you import an OpenAPI document, but convert it to their own internal format and provide no way to pull the OpenAPI back out again.

一些编辑器会在部分API设计生命周期中为您提供帮助,但会对您要执行的顺序做出许多困难的假设。他们可能会帮助您创建设计,然后假设您想要导出它并生成一些代码,使机器可读的描述文档变得四处飘荡,变得过时,并且即使您愿意,也无法对其进行编辑。 其他工具可让您导入OpenAPI文档,但将其转换为自己的内部格式,并且无法提供再次撤回OpenAPI的方法。

Using tools where the format changes entirely at different points locks you into whatever workflows they support, instead of letting you plug-and-play your own tooling at every stage of the process. For me the ideal solution is supporting a git-based flow, where they live in the repository (maybe before the code exists), and regardless of how these API descriptions were created you can edit them and send a pull request back to that repo with the changes you made.

使用格式在不同点完全改变的工具将您锁定在它们支持的任何工作流程中,而不是让您在流程的每个阶段即插即用。 对我而言,理想的解决方案是支持基于git的流,它们驻留在存储库中(可能在代码存在之前),并且无论如何创建这些API描述,您都可以对其进行编辑,并使用以下命令将拉取请求发送回该存储库您所做的更改。

Leaving the machine-readable source of truth in the repo means any integrations are possible. Continuous integration processes can deploy documentation to any documentation provider, you can use use any code-generators to build and publish SDKs, sync with popular HTTP clients like Postman or Insomnia instead of maintaining API descriptions and bookmarks, and fully take care of contract testing in-repo or end-to-end repositories. If your editor is backed by a design library then the repositories will be analyzed on push, allowing others to use these updated models instead of having 1000 different versions of a “User”, “Company” or a “Flight”.

在回购中保留机器可读的真实来源意味着可以进行任何集成。 持续集成过程可以将文档部署到任何文档提供者,您可以使用任何代码生成器来构建和发布SDK,与诸如Postman或Insomnia之类的流行HTTP客户端同步,而无需维护API描述书签,并完全负责合同中的测试。 -repo或端到端存储库。 如果您的编辑器有设计库支持,则将在推送时分析存储库,从而允许其他人使用这些更新的模型,而不必使用1000个不同版本的“用户”,“公司”或“航班”。

Image for post
Enterprise users, but is now available for everyone. 企业用户可用,但现在对所有人都可用。

But, how does having an editor help you catch mistakes? Stoplight Studio has a built in HTTP Client, which amongst other things is watching for mismatches between the OpenAPI defined for the API and the actual HTTP requests you send. It will also notice mismatches between OpenAPI and the responses coming back, so you’ll see mistakes popping up like this:

但是,拥有编辑器如何帮助您发现错误? Stoplight Studio具有一个内置的HTTP客户端 ,它除其他外还监视为该API定义的OpenAPI与您发送的实际HTTP请求之间的不匹配。 它还会注意到OpenAPI和返回的响应之间不匹配,因此您将看到错误弹出,如下所示:

Image for post

Noticing contract mismatches in a HTTP client is all well and good for spotting mistakes in requests you’re making, but you’ll want to automate this checking too.

注意HTTP客户端中的合同不匹配非常适合发现正在发出的请求中的错误,但是您也想使此检查自动化。

Instead of having all your model validation rules and header checking written in code, and then also writing it down in the API descriptions, use the existing machine-readable descriptions for validating incoming requests. If your request logic is powered by API descriptions, there is no need to check that it matches the code, because it… is the code. Framework middlewares for every framework and every language implement this. NodeJS has about 100.

与其使用代码编写所有模型验证规则和标头检查,然后再将其写到API描述中,不如使用现有的机器可读描述来验证传入请求 。 如果您的请求逻辑由API描述提供支持,则无需检查它是否与代码匹配,因为它是代码。 每个框架和每种语言的框架中间件都可以实现此目的。 NodeJS大约有100个。

The Rails one, for example, takes a single line to set up the Rack middleware:

例如,Rails只需一行即可设置Rack中间件:

use Committee::Middleware::RequestValidation,
schema_path: "./openapi.yaml"

That covers incoming requests, but how to ensure the responses are doing the right thing? Some of those middlewares will implement response validation too, which can confirm the response coming through it matches the code. This is a great thing to enable in dev and staging, but turn that off for production. 🤣

这涵盖了传入的请求,但是如何确保响应做正确的事情? 这些中间件中的一些也将实现响应验证,这可以确认通过它来的响应与代码匹配。 在开发和暂存中启用这是一件了不起的事情,但是将其关闭以进行生产。 🤣

Another approach to checking responses is contract testing. Instead of having some DSL-based integration testing suite specifically for checking the responses, or using some other tool where you have to write out the contract again, you can can just use the API descriptions as contract tests. So easy, and all it takes is a few lines of code to mush the response into a data validator for the API description format of your choice.

检查响应的另一种方法是合同测试。 除了拥有一些专门用于检查响应的基于DSL的集成测试套件或在必须再次写出合同的地方使用其他工具之外,您可以仅将API描述用作合同测试 。 如此简单,只需几行代码即可将响应粘贴到您选择的API描述格式的数据验证器中。

Another approach is using Prism Proxy in end-to-end testing to blow up if any requests or responses are invalid throughout the test suite. This can be implemented with little to no buy in from the folks producing the APIs, because you can just funnel existing cross-API traffic through the proxy in the testing environment without modifying any code.

另一种方法是在端到端测试中使用Prism代理 ,以在整个测试套件中发现任何请求或响应无效的情况。 几乎不需要生产API的人就能实现这一点,因为您可以在测试环境中通过代理将现有的跨API流量集中到一起,而无需修改任何代码。

Code first and editors do not jive at all, because the editors do not understand the annotation system in the Java/PHP/Pyhton/etc sourcecode. According to an extremely scientific poll on my Twitter, 35% of teams are battling through with a mixture of code-first and design-first.

代码优先和编辑者根本不喜欢,因为编辑者不理解Java / PHP / Pyhton / etc源代码中的注释系统。 根据我在Twitter上进行的一项非常科学的民意测验 ,有35%的团队在代码优先和设计优先之间进行了斗争。

Image for post

So long as the code-first folks add a build step (pre-commit or in CI) to generate a machine-readable file in the filesystem (like openapi.yaml), then hosted solutions like Stoplight Platform can analyze repo contents to give the same hosted docs, mocks, and design libraries, to all the projects. No editing for them of course, but those who want editors are on the same remaining workflow as those who don't. 🥳

只要代码优先人员添加构建步骤(预先提交或在CI中)以在文件系统中生成机器可读文件(如openapi.yaml ),然后托管解决方案(如openapi.yaml Platform)就可以分析回购内容以提供所有项目都使用相同的托管文档,模拟和设计库。 当然,不需要编辑,但是想要编辑的人和不想要编辑的人在相同的剩余工作流程中。 🥳

注释即代码Web框架 (Annotations-as-Code Web Frameworks)

Many web-frameworks third-party support for request/response validation, which we’ve mentioned above. This is usually in the form of middlewares or just baked right in, and they read API descriptions from the filesystem.

我们上面已经提到了许多Web框架第三方对请求/响应验证的支持。 这通常是中间件的形式,或者只是直接引入,它们从文件系统读取API描述。

Other frameworks have first-party or third-party support for annotations, which are purely descriptive repetitions of the actual code they sit above at best. At worst they’re just lies.

其他框架具有注释的第一方或第三方支持,这些注释充其量只是它们上面的实际代码的纯粹描述性重复。 最糟糕的是,它们只是谎言。

There is a new category of API description integration popping up in some web frameworks which is somewhat like Annotations or DSLs, but instead of being purely descriptive it’s actually powering logic and reducing code, giving you one source of truth. Effectively they do the same thing as the machine-readable powered validation middlewares, but instead of coming from openapi.yaml the logic is coming from the annotations.

在某些Web框架中,出现了一种新的API描述集成类别,有点类似于注释或DSL,但实际上不是在提供纯粹的描述性,而是在增强逻辑并减少代码,从而为您提供了一个真实的来源。 实际上,它们的作用与机器可读的验证中间件相同,但是逻辑不是来自openapi.yaml ,而是来自注释。

Here’s an example from tsoa, which is a TypeScript and NodeJS framework for building OpenAPI-compliant REST APIs.

这是tsoa的示例,它是用于构建与OpenAPI兼容的REST API的TypeScript和NodeJS框架。

import { Body, Controller, Get, Header, Path, Post, Query, Route, SuccessResponse } from 'tsoa';
import { User, UserCreationRequest } from '../models/user';
import { UserService } from '../services/userService';
@Route('Users')
export class UsersController extends Controller {
@Get('{id}')
public async getUser(id: number, @Query() name: string): Promise<User> {
return await new UserService().get(id);
}
@SuccessResponse('201', 'Created') // Custom success response
@Post()
public async createUser(@Body() requestBody: UserCreationRequest): Promise<void> {
new UserService().create(request);
this.setStatus(201); // set return status 201
return Promise.resolve();
}
}

This is a brand new approach. Instead of descriptive annotations or comments shoved in as an afterthought, the API framework has been designed around the use of annotations.

这是一种全新的方法。 API框架不是围绕事后使用的说明性注释或注释,而是围绕注释的使用而设计的。

Beyond simple things like request validation, TSOA handles authentication quite nicely. Numerous times I’ve seen API documentation say bearer tokens are required, or an OAuth token needs a certain scope, only to find out the developer forgot to register that in the API controller. Free sensitive data anyone?

除了请求验证之类的简单事情之外, TSOA还可以很好地处理身份验证 。 我无数次看到API文档说,需要承载令牌,或者OAuth令牌需要一定范围,只是为了发现开发人员忘记在API控制器中注册它。 免费提供敏感数据吗?

TSOA solves that by having you register security definitions, then reference them in your annotations, and have middlewares created to handle the actual logic. This way the annotations are all the actual source of truth for authentication, instead of just being lies in comments or YAML.

TSOA通过注册安全性定义,然后在批注中引用它们并创建中间件来处理实际逻辑来解决此问题。 这样,注释便是身份验证的全部真实来源,而不仅仅是位于注释或YAML中。

Then, OpenAPI can be generated from a command:

然后,可以从以下命令生成OpenAPI:

tsoa spec

Whilst I definitely have a preference for design-first development for all the prototyping benefits it brings (changing a few lines of YAML in an awesome GUI is easier than rewriting a bunch of code every time you get feedback on a prototype), this new approach for making annotations useful is very much closing the gap. If you’re going to use a code-first approach, you should absolutely try and find a framework like TSOA to power your API and reduce the chance of mismatches.

尽管我绝对偏爱设计优先开发,因为它带来了所有原型制作上的好处(在真棒GUI中更改几行YAML比每次在收到原型反馈时重写一堆代码都容易),但是这种新方法使注释有用的方法大大缩小了差距。 如果要使用代码优先的方法,则绝对应该尝试找到像TSOA这样的框架来增强您的API并减少不匹配的机会。

Ideally the file-based middlewares and these new annotation-driven middlewares would share a bunch of dependencies. As I mentioned before there’s a million of these file-based validation middlewares out there, and some get more love and attention than others. I convinced three PHP request validation middleware authors to combine efforts and make one amazing one, so it’d be great if some of these other middleware developers could team up with some annotations-as-code framework people to allow them as inputs to their existing middleware. With OpenAPI v3.1.0 coming out soon, it’ll be a lot better for us tooling vendors to start collaborating on a smaller number of higher quality tools, instead of everyone battling through the upgrade process individually.

理想情况下,基于文件的中间件和这些新的注释驱动的中间件将共享一堆依赖关系。 正如我之前提到的那样,那里有百万种基于文件的验证中间件,其中一些比其他人更受关注和关注。 我说服了三位PHP请求验证中间件作者共同努力,做出了一件令人惊讶的事情 ,因此,如果这些其他中间件开发人员中的一些人可以与一些注释编码框架一起工作,以允许他们作为他们现有的输入,那将是一个很好的选择。中间件。 随着OpenAPI v3.1.0即将面世 ,对于我们的工具供应商来说,开始使用少量的更高质量的工具进行协作会好得多,而不是每个人都独自应对升级过程。

Whatever you’re up to: code-first, or design-first, make sure you’re doing what you can to avoid maintaining two sources of truth. Of all the options possible, try and stick to:

无论您做什么工作:代码优先或设计优先,请确保您正在尽自己所能避免维护两个事实来源。 在所有可能的选择中,尝试并坚持:

a) awesome editors like Stoplight Studio or GraphQL Designer to maintain API description documents, then reference them in the code, or

a)很棒的编辑器(例如Stoplight StudioGraphQL Designer)来维护API描述文档,然后在代码中引用它们,或者

b) frameworks which support annotations-as-code that knows how to express itself as API descriptions

b)支持注释即代码的框架,该框架知道如何将自身表示为API描述

Just don’t maintain code and descriptions separately, because having two sources of truth just means waste time trying to find out which one of them is lying.

只是不要分开维护代码和描述,因为拥有两个事实来源仅意味着浪费时间试图找出其中的一个。

翻译自: https://medium.com/apis-you-wont-hate/theres-no-reason-to-write-openapi-by-hand-2955f64de668

openapi

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐