Skip to main content

基于 OpenAPI 规范实现 Bookings API

将 YAML 规范文件交给 Devin,即可生成完整实现的 Express 路由处理器、Prisma 模型、Zod 校验逻辑,以及 Supertest 集成测试——并与现有代码库的模式保持一致。
AuthorCognition
Category功能开发
1

(可选)调研你现有的 API 设计模式

如果你不确定你的 Express API 是如何构建的,或者不清楚应该参考哪些模式,可以先使用 Ask Devin 来了解情况:你也可以使用 DeepWiki 来探索具有类似模式的开源 API——例如搜索 Express + Prisma + Zod 示例,查看其他项目如何组织路由处理程序和验证逻辑。你还可以直接从 Ask Devin 启动 Devin 会话,它会自动继承前面获取的所有上下文信息。
2

为 Devin 指定你的 OpenAPI 规范

首先告诉 Devin 规范文件位于何处,以及要实现哪个资源。Devin 会读取 YAML 中的每个路径、schema 和错误定义,然后与现有的 Express 路由进行交叉比对,自动匹配既有约定。下面是 Devin 能处理的这类规范的一个节选——针对 bookings 资源的标准 OpenAPI 3.0 定义:
# openapi/bookings-v2.yaml(节选)
openapi: "3.0.3"
info:
  title: Bookings API
  version: "2.0.0"
paths:
  /api/v2/bookings:
    get:
      summary: List bookings
      parameters:
        - name: page
          in: query
          schema: { type: integer, default: 1 }
        - name: startDate
          in: query
          schema: { type: string, format: date }
        - name: endDate
          in: query
          schema: { type: string, format: date }
      responses:
        "200":
          description: Paginated list of bookings
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BookingListResponse"
    post:
      summary: Create a booking
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateBookingInput"
      responses:
        "201":
          description: Booking created
        "409":
          description: Time slot conflict
  /api/v2/bookings/{id}/confirm:
    post:
      summary: Confirm a booking
      responses:
        "200":
          description: Booking confirmed
        "422":
          description: Booking already cancelled
components:
  schemas:
    CreateBookingInput:
      type: object
      required: [title, startTime, endTime, roomId]
      properties:
        title:
          type: string
          maxLength: 200
        startTime:
          type: string
          format: date-time
        endTime:
          type: string
          format: date-time
        roomId:
          type: string
          format: uuid
如果你的规范文件还没有提交到代码仓库,请在会话中直接粘贴它,或者在开始时附上该 YAML/JSON 文件。
3

Devin 兼容你的 Express 路由模式

你能做的最有成效的一件事,就是在代码库中引用一个实现良好的资源作为范例。Devin 会学习这段代码,并复制其文件夹结构、命名约定、中间件链和错误处理方式——这样生成的新端点看起来就像是由同一位开发者编写的。例如,Devin 会阅读 src/api/v2/users/router.ts,并生成一个对应的 bookings 路由:
// src/api/v2/bookings/router.ts  (由 Devin 生成)
import { Router } from "express";
import { authenticate } from "@/middleware/auth";
import { validate } from "@/middleware/validate";
import { BookingsController } from "./controller";
import {
  createBookingSchema,
  updateBookingSchema,
  listBookingsQuerySchema,
} from "./schemas";

const router = Router();
const ctrl = new BookingsController();

router.use(authenticate);

router.get("/", validate({ query: listBookingsQuerySchema }), ctrl.list);
router.post("/", validate({ body: createBookingSchema }), ctrl.create);
router.get("/:id", ctrl.getById);
router.patch("/:id", validate({ body: updateBookingSchema }), ctrl.update);
router.delete("/:id", ctrl.softDelete);
router.post("/:id/confirm", ctrl.confirm);
router.post("/:id/cancel", ctrl.cancel);

export default router;
Devin 还会直接根据 OpenAPI 组件定义生成 Zod schema,这样请求验证就能与规范保持同步:
// src/api/v2/bookings/schemas.ts  (generated by Devin)
import { z } from "zod";

export const createBookingSchema = z.object({
  title: z.string().max(200),
  startTime: z.string().datetime(),
  endTime: z.string().datetime(),
  roomId: z.string().uuid(),
  notes: z.string().max(1000).optional(),
});

export const updateBookingSchema = createBookingSchema.partial();

export const listBookingsQuerySchema = z.object({
  page: z.coerce.number().int().positive().default(1),
  limit: z.coerce.number().int().min(1).max(100).default(20),
  startDate: z.string().date().optional(),
  endDate: z.string().date().optional(),
});
请确保你的代码库设置中包含测试数据库配置和所有所需的环境变量,以便 Devin 能在本地运行完整的测试套件。若你的 API 需要凭证(数据库 URL、JWT 密钥等),请在开始会话前将它们添加为 Secrets,或在会话过程中通过聊天提供这些信息。
4

Devin 提交经过测试的拉取请求(PR)

Devin 会阅读规范说明,分析你现有的代码,并为每个 endpoint 编写实现,使其同时符合 OpenAPI 规范和你的 Express 代码库约定。下面是一个典型的 PR(pull request)示例:
feat: Implement /api/v2/bookings endpoints from OpenAPI spec

src/api/v2/bookings/
  router.ts              (Express route definitions + middleware)
  controller.ts          (request handling)
  service.ts             (business logic)
  repository.ts          (Prisma queries)
  schemas.ts             (Zod validation from spec)
prisma/migrations/
  20260219_add_bookings/  (migration)
src/__tests__/
  bookings.integration.ts (Supertest tests)
在发起 PR 之前,Devin 会运行 Supertest 测试套件:
  /api/v2/bookings
    GET /
      passes returns paginated bookings (42ms)
      passes filters by date range (38ms)
      passes returns 401 without auth (8ms)
    POST /
      passes creates booking with valid data (61ms)
      passes returns 400 for missing required fields (12ms)
      passes returns 409 for overlapping time slot (29ms)
    PATCH /:id
      passes updates booking fields (22ms)
      passes returns 404 for non-existent booking (9ms)
    POST /:id/confirm
      passes transitions status to confirmed (18ms)
      passes returns 422 for already-cancelled booking (11ms)

  16 passing (412ms)
5

在规范未涵盖的内容上进行迭代

The OpenAPI 规范定义了接口契约,但很少涵盖业务规则、授权逻辑或性能要求。使用后续提示来补充这些空白:
6

使用 Devin Review 审查此 PR

一旦 Devin 创建 PR,使用 Devin Review 来审查实现。Devin Review 可以发现诸如缺少错误处理、响应格式不一致,或者端点与规范不匹配之类的问题。如果 Devin Review 指出了问题,你可以使用 Autofix 让 Devin 自动修复这些被标记的问题——它会开启一个后续会话,应用修复,并推送更新后的提交,而你无需手动逐一描述每项更改。