为了将我的前端接口连接到数据库,我需要设计一个 API 来允许前端应用程序检索和发送数据。这将启用我的用户逻辑,例如创建帐户、登录和退出等。它将启用围绕烘焙的所有逻辑。
我之前创建过 Express API,但这次我想看看是否可以在构建过程中了解更多有关 Swagger 的知识。
Swagger 是一家设计和维护三种产品的公司,Swagger Editor、Swagger CodeGen 和 Swagger UI。这三个产品携手合作,使创建符合 OpenAPI 的应用程序(和文档)变得更加容易!
使用 Swagger 创建 API 的过程从 Swagger 编辑器开始。该工具允许您创建所谓的合同。合约是一个 YAML 文档,它定义了有关应用程序的不同内容,例如名称、它将处理的路由等等。
如果您以前没有使用过 YAML,它是一种更宽松的基于对象的标记语言,与 JSON 有一些相似之处,但更容易快速输入。以下是 JSON 和 YAML 中相同内容的示例:
// JSON Example { "name": "ThisApp", "description": "An example of data.", "list": [ "option1", "option2", "option3" ], "object": { "key": "value" } }
# YAML Example name: ThisApp description: An example of data. list: - option1 - option2 - option3 object: key: value
请注意,YAML 虽然仍然是机器可读的,但对于人类来说也更容易阅读,这使其成为此规范的绝佳标记语言。
使用 Swagger 编辑器并遵循 OAS,您可以编写出通常编程到 API 中的所有内容。
在顶层,您将定义应用程序的细节:
openapi: 3.0.3 info: title: Roast - Know Your Home Roasts description: # This will appear in the API UI version: 1.0.0 servers: - url: # A url to one or more servers here tags: These are groups of paths - name: user description: Operations for your user - name: roast description: Access to roasts paths: # Define all of your paths in this object components: # Define reusable pieces of code here
当您开始定义路径时,代码编辑器的魔力就会显现出来。采用我定义的以下路径,通过 id 获取单个烘焙。
# ... contract information paths: # ... users paths, etc. /roasts/{roastId}: get: tags: - roast summary: Get roast by id description: Must include a valid roast id parameters: - $ref: '#/components/parameters/roastIdParam' responses: '200': description: Successful operation content: application/json: schema: $ref: "#/components/schemas/Roast" '400': $ref: '#/components/responses/Invalid' '404': $ref: '#/components/responses/NotFound'
让我们分解这个对象。首先,它被称为/roasts/{roastId}。这意味着我们正在定义当请求发送到此路由时服务器的预期行为。下面会发生什么?
开发这样的合约,您可能会发现自己一遍又一遍地输入相同的内容。作为一名程序员,您可能知道我们要遵循 DRY 原则:“不要重复自己”。例如,当定义一个必需的请求体时,可能会有多个端点需要同一个对象。
这就是组件的用武之地。对于这个示例,您可以定义一个架构,然后使用 $ref 在合约中的任何位置引用该架构: .
所以,在我的合约底部,我有一个组件:对象。
components: schemas: Roast: # An arbitrary name to identify the schema type: object properties: id: type: integer format: int64 example: 10 ## Include all other properties
这个组件对象包含一个名为 Roast 的模式,所以现在,如果我需要指定需要在请求中发送该对象,例如在对 /roast 的 POST 请求中发送以添加新的烘焙。我可以这样引用该对象:
/roast: post: # additional specifications requestBody: content: application/json: schema: $ref: '#/components/schemas/Roast'
您还可以在定义参数和规范的许多其他重复部分中执行此操作!
当您在 Swagger 编辑器中打字时,右侧窗口中的 Swagger UI 一直在不断更新。 Swagger UI 正在更新将成为您的 API 文档的内容!这意味着您不必稍后返回并自己编写文档。
最好的部分是,它将与您的应用程序一起提供(只要您使用 CodeGen 创建它)。
Once you feel like your API is up to spec, you can have a working server in 17 different languages/frameworks in seconds! Just click Generate Server, and select your flavor and CodeGen reads your OAS spec and downloads a server.
In Node, your code comes out in a few different directories.
generated-server/ |-- api/ |-- controllers/ |-- service/ |-- utils/ |-- README.md |-- index.js |-- package.json
The api directory contains your OpenAPI spec. The controllers directory contains a file for each of your path groups, with exported functions specifically for handling the unique paths and operations of your application. The service directory, is where you will hook these operations up to your database and perform the business logic of the application, and utils contains functions that help read and write data.
Your server will actually live in index.js.
Yes! Well, sort of.
CodeGen does in fact make a working server for you, but it's still up to you to hook up the database and design the logic of the application! But, it gives you a complete and organized skeleton that you can work in!
Here's an example of the code that it output for my POST request to /roasts .
// controllers/Roast.js // ... module.exports.addRoast = function addRoast (req, res, next, body) { Roast.addRoast(body) .then(function (response) { utils.writeJson(res, response); }) .catch(function (response) { utils.writeJson(res, response); }); }; // service/RoastService.js // ... exports.addRoast = function(body) { return new Promise(function(resolve, reject) { var examples = {}; examples['application/json'] = { "notes" : "Doesn't taste as good as last time... I wonder if the weather is making the beans roast faster now that it's warmer", "heatLevel" : "Med", "origin" : "Ethiopian", // ... "id" : 10, }; if (Object.keys(examples).length > 0) { resolve(examples[Object.keys(examples)[0]]); } else { resolve(); } }); }
The above code was entirely generated by Swagger CodeGen. However, it won't actually add a roast object anywhere. This is creating a mock object and sending it back. But, after hooking up a Postgres database, and creating queries with this logic inside the service, the API will be fully operational!
I loved working with Swagger on this API, it was the first time that I committed to learning some of the intricacies of OAS to generate the server. The only rub that I have with it is that the docs are not formatted the best, and they can be hard to navigate searching for what you want to add to the server.
But, once you're familiar with OAS, this tool can save a ton of time. Not only do you have extremely thorough documentation when you're done, but you can treat the generated code as a to-do list of the functions and logic that you need to implement as you build!
Would you give it a try?
If you want to keep up with the changes, fork and run locally, or even suggest code changes, here’s a link to the GitHub repo!
https://github.com/nmiller15/roast
The frontend application is currently deployed on Netlify! If you want to mess around with some features and see it in action, view it on a mobile device below.
https://knowyourhomeroast.netlify.app
Note: This deployment has no backend api, so accounts and roasts are not actually saved anywhere between sessions.
以上是[Roast:Day - 无需 AI 自动创建 API 服务器的详细内容。更多信息请关注PHP中文网其他相关文章!