Skip to content

บทที่ 5 — OpenAPI + Documentation

← บทที่ 4 | สารบัญ | บทที่ 6 →

หลังจบบท คุณจะ:

  • เขียน OpenAPI spec (3.1)
  • Generate doc อัตโนมัติจาก Spring Boot (springdoc)
  • ใช้ Swagger UI / ReDoc / Scalar
  • Generate client code จาก spec (TypeScript, Java, Python)
  • Contract-first design

1. ทำไม Documentation สำคัญ

API ไม่มี doc = API ใช้ไม่ได้:

  • Frontend dev ต้องเดาว่า field อะไรบ้าง
  • Partner ใช้ไม่ได้
  • 6 เดือนต่อมา — ตัวคุณเองลืม

กฎ: doc = part of code — ไม่ใช่ "ทำหลังเสร็จ"


2. ระดับของ API Doc

API doc มีหลายระดับวุฒิภาวะ ไล่จากแย่สุด (ไม่มี/อ่านโค้ดเอา) ไปจนถึงดีสุด (API portal เต็มรูปแบบ) — แต่ละระดับแลกระหว่างความง่ายกับประโยชน์ที่ได้ ปี 2026 มาตรฐานคือ OpenAPI 3.1 ที่ machine-readable และ generate ของต่อได้:

Levelคืออะไร
Nonecode คือ doc 😱
Markdownmanual, sync ยาก
Postman collectionusable, manual
OpenAPI specmachine-readable, auto-generate doc + client
Interactive DocSwagger UI, try-it-out
API Portalfull developer experience

ปี 2026 mass standard = OpenAPI 3.1 (อ่าน "โอ-เพน-เอ-พี-ไอ" — ของเดิมชื่อ Swagger อ่าน "สแว็ก-เกอร์" เปลี่ยนชื่อปี 2015)


3. OpenAPI คืออะไร

OpenAPI คือมาตรฐานสำหรับเขียน "คำอธิบาย" REST API เป็นไฟล์ YAML/JSON ที่เครื่องอ่านได้ — พลังของมันคือเป็น single source of truth ที่ generate ได้ทั้ง doc, client (หลายภาษา), server stub, mock และ test ทำให้ทุกอย่างซิงค์กับ API จริง:

OpenAPI (เดิม Swagger) = มาตรฐาน สำหรับ describe REST API

📝 YAML 101 (1 ย่อหน้า): YAML ใช้ indent (space) แทน {} ของ JSON, - คือ item ของ list, : คือ key:value, indent 2 space ถือว่าอยู่ใต้ parent — ผิด indent 1 ตัว = parse fail (เคร่งกว่า Python)

yaml
openapi: 3.1.1                   # ปี 2026 ใช้ 3.1.x (3.1.1 release ต.ค. 2024) — ผมใช้ "3.1" สั้น ๆ ก็ได้
info:
  title: Bookstore API
  version: 1.0.0
  description: API for managing books
servers:
  - url: https://api.example.com/v1
paths:
  /books:
    get:
      summary: List books
      parameters:
        - name: page
          in: query
          schema:
            type: integer
            default: 0
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookList'   # $ref = pointer ไปหา schema อื่นในไฟล์เดียวกัน
                                                       # #/components/schemas/BookList = ไปที่ components > schemas > BookList
components:
  schemas:
    Book:
      type: object
      properties:
        id: { type: integer }
        title: { type: string }
        author: { type: string }

💡 หมายเหตุ price: ตัวอย่างนี้ใช้ type: number, format: float พอเข้าใจ แต่ เงินจริงไม่ควรใช้ float (เสีย precision) — ใน production ใช้ type: string, format: decimal หรือ type: number, multipleOf: 0.01 ให้ตรงกับ NUMERIC ใน DB (ดูบท 1 ของ DB chapter)

ไฟล์นี้ (openapi.yaml) = single source of truth

  • Generate doc (Swagger UI, ReDoc)
  • Generate client (TypeScript, Java, Python)
  • Generate server stub
  • Generate mock server
  • Test (Postman, schemathesis)
  • Validate request/response

4. OpenAPI Structure

ไฟล์ OpenAPI มีโครงสร้างหลักไม่กี่ส่วน — info (metadata), servers (URL), paths (endpoint แต่ละตัว) และ components (schema/security ที่ reuse ได้) เข้าใจผังนี้แล้วจะอ่านและเขียน spec ของ API ใดก็ได้:

openapi: <version>
info:
  title, version, description, contact, license
servers:
  - url, description
paths:
  /endpoint:
    get/post/put/...:
      summary, description
      parameters
      requestBody
      responses
      security
      tags
components:
  schemas: <type definitions>
  parameters: <reusable params>
  responses: <reusable responses>
  securitySchemes: <auth definitions>
security: <default security>
tags: <grouping>

5. ตัวอย่างเต็ม

มาดู OpenAPI spec ที่สมบูรณ์ของ API จริง — Bookstore API ที่มีครบทั้ง info, security scheme, หลาย path พร้อม parameter/response และ component schema ใช้เป็นแบบในการเขียน spec ของโปรเจกต์เองได้:

yaml
openapi: 3.1.1

info:
  title: Bookstore API
  version: 1.0.0
  description: |
    REST API for online bookstore.
    
    ## Features
    - Browse books
    - User management
    - Order processing
  contact:
    email: api@example.com
  license:
    name: MIT

servers:
  - url: https://api.example.com/v1
    description: Production
  - url: https://staging-api.example.com/v1
    description: Staging
  - url: http://localhost:8080/api/v1
    description: Local dev

tags:
  - name: Books
    description: Book operations
  - name: Users
    description: User management

paths:
  /books:
    get:
      tags: [Books]
      summary: List books
      description: Get a paginated list of books
      operationId: listBooks
      parameters:
        - name: page
          in: query
          schema:
            type: integer
            default: 0
            minimum: 0
        - name: size
          in: query
          schema:
            type: integer
            default: 20
            minimum: 1
            maximum: 100
        - name: author
          in: query
          schema:
            type: string
        - name: search
          in: query
          schema:
            type: string
      responses:
        '200':
          description: List of books
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookPage'

    post:
      tags: [Books]
      summary: Create book
      operationId: createBook
      security:
        - BearerAuth: [admin]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateBookRequest'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Book'
        '400':
          $ref: '#/components/responses/ValidationError'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'

  /books/{id}:
    get:
      tags: [Books]
      summary: Get book
      operationId: getBook
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Book
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Book'
        '404':
          $ref: '#/components/responses/NotFound'

components:
  schemas:
    Book:
      type: object
      required: [id, title, author, price]
      properties:
        id:
          type: integer
          example: 1
        title:
          type: string
          example: "1984"
        author:
          type: string
          example: "George Orwell"
        isbn:
          type: string
          pattern: '^[0-9-]+$'                # ⚠️ simplified — ของจริงต้อง check digit (10/13 digit + checksum)
          example: "978-0-451-52493-5"
        price:
          type: string                        # ⭐ เงินใช้ string-decimal เลี่ยง float precision (ตรงกับ NUMERIC ใน DB)
          format: decimal
          pattern: '^\d+\.\d{2}$'
          example: "12.99"
        stock:
          type: integer
          minimum: 0
          example: 50
        publishedYear:
          type: integer
          example: 1949
        createdAt:
          type: string
          format: date-time
          example: "2026-05-18T10:00:00Z"
    
    CreateBookRequest:
      type: object
      required: [title, author, price]
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 255
        author:
          type: string
          minLength: 1
        isbn:
          type: string
        price:
          type: string                        # ⭐ string-decimal เพื่อเลี่ยง float rounding
          format: decimal
          pattern: '^\d+\.\d{2}$'
        stock:
          type: integer
          minimum: 0
          default: 0
    
    BookPage:
      type: object
      properties:
        content:
          type: array
          items:
            $ref: '#/components/schemas/Book'
        page:
          type: integer
        size:
          type: integer
        total:
          type: integer
    
    Error:
      type: object
      properties:
        type: { type: string }
        title: { type: string }
        status: { type: integer }
        detail: { type: string }
        traceId: { type: string }

  responses:
    NotFound:
      description: Resource not found
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Error'
    ValidationError:
      description: Validation failed
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Authentication required
    Forbidden:
      description: Insufficient permission

  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
    OAuth2:                                       # ปี 2026 OAuth2 พบบ่อยกว่า bearer ปกติ
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://auth.example.com/authorize
          tokenUrl: https://auth.example.com/token
          scopes:
            read: Read access
            write: Write access
            admin: Admin access

security:
  - BearerAuth: []

6. Springdoc — Auto-generate from Spring Boot

เขียน YAML เองทั้งหมดเสี่ยงไม่ตรงกับโค้ดจริง — Springdoc generate OpenAPI spec จาก controller + DTO ของ Spring Boot ให้อัตโนมัติ พร้อม Swagger UI สำหรับทดลองยิง API จาก browser ทำให้ doc ซิงค์กับโค้ดเสมอโดยไม่ต้องดูแลแยก:

วาง XML นี้ใน pom.xml ใต้ <dependencies> (Maven) — ถ้าใช้ Gradle ก็แปลงเป็น implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.7.0' ใน build.gradle:

xml
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.7.0</version>   <!-- ปี 2026: 2.7.x+ (รองรับ Spring Boot 3.x) — เช็คเวอร์ชันล่าสุดที่ https://springdoc.org/ -->
</dependency>

Start app → เปิด:

ไม่ต้องเขียน YAML — Springdoc generate จาก controller + DTO


7. Annotations เสริม (Spring + Springdoc)

Springdoc เดาส่วนใหญ่ได้เอง แต่บางอย่างต้องบอกเพิ่มเพื่อให้ doc ครบและอ่านดี — @Operation (อธิบาย endpoint), @Schema (อธิบาย field + example), @ApiResponse (response แต่ละ status) annotation กลุ่มนี้ช่วยให้ doc มีคุณภาพระดับใช้งานจริง:

java
@RestController
@RequestMapping("/api/v1/books")
@Tag(name = "Books", description = "Book operations")
public class BookController {
    
    @GetMapping
    @Operation(summary = "List books", description = "Get paginated books")
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "OK"),
        @ApiResponse(responseCode = "400", description = "Bad Request")
    })
    public Page<BookResponse> list(
        @Parameter(description = "Search query") @RequestParam(required = false) String search,
        @ParameterObject Pageable pageable
    ) {
        return bookService.list(search, pageable);
    }
    
    @PostMapping
    @Operation(summary = "Create book", security = @SecurityRequirement(name = "BearerAuth"))
    public BookResponse create(@RequestBody @Valid CreateBookRequest req) {
        return bookService.create(req);
    }
}
java
@Schema(description = "Book entity")
public record BookResponse(
    @Schema(example = "1") Long id,
    @Schema(example = "1984") String title,
    @Schema(example = "George Orwell") String author,
    @Schema(example = "12.99") BigDecimal price
) {}

@Schema(description = "Request to create a book")
public record CreateBookRequest(
    @NotBlank @Size(max = 255) String title,
    @NotBlank String author,
    @NotNull @DecimalMin("0") BigDecimal price
) {}

8. OpenAPI Tools

Documentation

  • Swagger UI (สแว็ก-เกอร์) — interactive, popular (default ของ springdoc) — UI สไตล์เก่า (legacy)
  • Redocly / ReDoc (รี-ด็อก) — clean, 3-pane, ดีสำหรับ public API
  • Scalar (สเก-ลาร์) ⭐ (2024+) — modern, beautiful, dark mode, popular ในปี 2026
  • Stoplight Elements (สตอป-ไลท์) — embeddable
  • Mintlify (มินท์-ลิ-ฟาย) — modern doc platform (paid)
  • RapiDoc (แร-พิ-ด็อก) — customizable web component

Swagger UI vs Scalar (ปี 2026)

Swagger UI:
- Default ของ springdoc
- Mature, ทุกคนคุ้น
- UI สไตล์เก่า

Scalar:
- Modern UI (Stripe-like)
- Dark mode
- Fast loading
- Search-first
- Used by: Vercel, Better Auth, Hono

→ ปี 2026 บริษัทใหม่ ๆ ย้ายไป Scalar
html
<!-- ใช้ Scalar กับ Spring Boot — simple HTML -->
<!doctype html>
<html>
<head>
    <title>Scalar API Reference</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
    <script
        id="api-reference"
        data-url="/v3/api-docs"
    ></script>
    <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
</body>
</html>

Editor

  • Stoplight Studio (สตอป-ไลท์ สตู-ดิ-โอ) — visual editor (drag-and-drop)
  • Swagger Editor — online
  • VS Code with OpenAPI extension

Mock Server

  • Prism (พริซึม) — prism mock openapi.yaml
  • Mockoon (มอค-คูน)

Code Generation

  • openapi-generator — 50+ languages
  • openapi-typescript — modern TS

Validation

  • Spectral (สเป็ค-ทรัล) — lint OpenAPI spec (จาก Stoplight)
  • Swagger Validator

Testing — Contract Testing

  • Schemathesis (สคี-มา-ที-ซิส) — generate test จาก spec อัตโนมัติ
  • Pact (แพคท์) — consumer-driven contract testing (provider/consumer ทั้งสองฝั่ง)
  • Dredd (เดรด) — contract testing แบบเก่า

9. Generate TypeScript Client

จุดที่ OpenAPI คุ้มค่าที่สุดคือ generate client ให้ frontend — แปลง spec เป็น TypeScript type + client ที่ type-safe เมื่อ backend เปลี่ยน DTO ก็ re-generate แล้ว type ที่ผิดจะ error ทันทีตอน compile ไม่ต้องมานั่ง sync type ด้วยมือ:

bash
npm install -D openapi-typescript

# Generate types
# หมายเหตุ: /v3/api-docs — `v3` หมายถึง OpenAPI version 3 (path มาตรฐานของ springdoc)
npx openapi-typescript http://localhost:8080/v3/api-docs -o src/api/schema.ts
ts
// schema.ts (auto-generated)
export interface paths {
    "/books/{id}": {
        get: {
            parameters: { path: { id: number } };
            responses: {
                200: { content: { "application/json": components["schemas"]["Book"] } };
                404: { content: { ... } };
            };
        };
    };
}

export interface components {
    schemas: {
        Book: {
            id: number;
            title: string;
            author: string;
            // ...
        };
    };
}

// ใช้
type Book = components['schemas']['Book'];
type GetBookResponse = paths['/books/{id}']['get']['responses']['200']['content']['application/json'];
// ↑ การ access nested type ของ TS แบบนี้คล้าย object key access — แต่ยาวมาก
//   ในงานจริงใช้ตัวช่วยอย่าง openapi-fetch (ดูข้างล่าง) ที่ wrap ให้เรียกสั้นและสะอาดกว่า

→ frontend type = backend DTO เปลี่ยน → re-generate → type-safe

Fully-typed Client

bash
npm install openapi-fetch
ts
import createClient from 'openapi-fetch';
import type { paths } from './schema';

const client = createClient<paths>({ baseUrl: '/api/v1' });

const { data, error } = await client.GET('/books/{id}', {
    params: { path: { id: 1 } }
});
// data is fully typed!

10. Generate Java Client

เช่นเดียวกับ TypeScript เราสร้าง client ภาษาอื่นจาก spec เดียวกันได้ — openapi-generator-cli รองรับ Java, Python, Go ฯลฯ เหมาะกับการแจก SDK ให้ partner ที่ integrate กับ API ของเรา โดยไม่ต้องเขียน HTTP call เอง:

ติดตั้งก่อน:

bash
# npm (cross-platform — ต้อง Java ติดตั้งอยู่)
npm install -g @openapitools/openapi-generator-cli

# หรือ macOS (Homebrew)
brew install openapi-generator

แล้ว generate:

bash
openapi-generator-cli generate \
    -i http://localhost:8080/v3/api-docs \
    -g java \
    -o ./generated-client \
    --library okhttp-gson

ใช้ใน partner app:

java
ApiClient client = new ApiClient().setBasePath("https://api.example.com/v1");
BooksApi books = new BooksApi(client);
Book book = books.getBook(1L);

11. Contract-First Design

แทนที่จะเขียน code ก่อน → generate doc → กลับกัน:

Step 1: Design OpenAPI spec ก่อน

yaml
# openapi.yaml
paths:
  /books:
    get: ...

Step 2: Review with team

Frontend + Backend + Mobile review → agree before coding

Step 3: Generate

  • Backend: server stub → fill business logic
  • Frontend: client + types
  • QA: mock server for testing
  • Doc: auto-publish

Step 4: Implement parallel

ทุกคนทำงานพร้อมกัน เพราะ contract แน่นอน

ทำไมดี

  • ✅ Discuss ก่อน code = ลด rework
  • ✅ Frontend + Backend ไม่ block กัน
  • ✅ Mock = frontend ทำงานได้ก่อน backend
  • ✅ Doc = always up-to-date

12. API Description ที่ดี

doc ที่ดีไม่ใช่แค่ลิสต์ field แต่ต้องอธิบาย "วิธีใช้จริง" — endpoint ทำอะไร, edge case, idempotency, error ที่เป็นไปได้ พร้อม example ที่ใช้งานได้ ส่วนนี้แสดงตัวอย่าง description ที่ช่วยให้ผู้เรียก API เข้าใจโดยไม่ต้องถาม:

yaml
paths:
  /payments:
    post:
      summary: Create a payment
      description: |
        Charges the user's card and creates a payment record.
        
        ## Idempotency
        
        Send `Idempotency-Key` header to safely retry. Same key 
        within 24 hours returns the original response.
        
        ## Webhooks
        
        On success/failure, a webhook is sent to your configured URL:
        - `payment.succeeded`
        - `payment.failed`
        
        ## Example
        
        ```bash
        curl -X POST https://api.example.com/v1/payments \
          -H "Authorization: Bearer sk_test_..." \
          -H "Idempotency-Key: $(uuidgen)" \
          -d '{"amount": 100, "currency": "usd"}'
        ```
      ...

ใส่:

  • Example
  • Edge cases
  • Side effects
  • Rate limit
  • Related endpoint

13. Changelog

API ที่มี consumer ภายนอกต้องมี changelog ที่ชัด — บอกว่าเวอร์ชันไหนเพิ่ม/แก้/deprecate อะไร โดยเฉพาะ breaking change และวัน sunset เพื่อให้ผู้ใช้เตรียมตัวย้ายได้ทัน ใช้ semantic versioning (MAJOR.MINOR.PATCH) เทมเพลตด้านล่างใช้ได้เลย:

markdown
# API Changelog

## v1.5.0 (2026-06-15)

### Added
- New endpoint `POST /webhooks/test` to send test webhook
- Field `metadata` in `Order` (optional)

### Deprecated
- Endpoint `GET /old-search` — use `GET /search` instead. Sunset: 2026-12-01

### Fixed
- 500 error when filtering by invalid date format (now returns 400)

## v1.4.0 (2026-05-01)

### Breaking
- Removed deprecated `GET /users/list` (use `GET /users`)

ใช้ semantic versioning: MAJOR.MINOR.PATCH


14. Postman / Bruno Collection

OpenAPI ดีสำหรับ doc แต่ตอนพัฒนา/ทดสอบ API ด้วยมือ Postman/Bruno สะดวกกว่า — เก็บ request ที่เคยใช้, สลับ environment (dev/staging/prod), เขียน test assertion Bruno เป็นทางเลือก open-source ที่เก็บเป็นไฟล์ commit เข้า git ได้:

นอก OpenAPI — Postman/Bruno collection ช่วย:

  • Test environment (dev, staging, prod)
  • Save request เคยใช้
  • Pre-request script
  • Test assertion
bash
# Export OpenAPI → Postman
# Postman → File → Import → paste OpenAPI URL

Bruno = open-source alternative (file-based, git-friendly)


15. API Portal — Developer Experience

สำหรับ public API ความสำเร็จขึ้นกับ "developer experience" — นักพัฒนาภายนอกต้องเริ่มใช้ได้เร็ว API portal รวม quickstart, reference (จาก OpenAPI), guide, sandbox และ SDK ไว้ที่เดียว ยิ่ง onboard ง่ายยิ่งมีคน integrate มาก:

สำหรับ public API — ทำ portal:

docs.example.com/
├── /                       # Landing
├── /quickstart             # 5-min tutorial
├── /reference              # Auto-generated from OpenAPI
├── /guides                 # How-to (auth, pagination, webhooks)
├── /changelog
├── /sandbox                # Try with API key
├── /support
└── /sdk                    # Download client libraries

Tools:

  • Stoplight Platform
  • Readme.io
  • Mintlify
  • Bump.sh

16. Spectral — Lint Your OpenAPI

💡 Lint คืออะไร? "lint" (ลินท์) มาจาก linter = เครื่องมือตรวจ style/มาตรฐานของไฟล์ คล้าย spell-check ของโค้ด (เช่น ESLint สำหรับ JavaScript)

เหมือนโค้ดที่มี linter, OpenAPI spec ก็ lint ได้ — Spectral (สเป็ค-ทรัล จาก Stoplight) ตรวจว่า spec ตามมาตรฐานและ convention ของทีมไหม (ทุก operation มี description? DELETE คืน 204?) ใส่ใน CI เพื่อกัน spec คุณภาพต่ำหลุดเข้า main:

bash
npm install -g @stoplight/spectral-cli

# Default rules
spectral lint openapi.yaml

# Custom rules
spectral lint openapi.yaml --ruleset my-rules.yaml

my-rules.yaml:

yaml
extends: spectral:oas
rules:
  operation-tags: error
  operation-description: error
  operation-operationId: error
  no-200-on-delete:
    given: "$.paths[*].delete.responses['200']"
    message: "DELETE should return 204"
    severity: warn          # team preference: HTTP spec อนุญาต DELETE → 200 ที่มี body ได้ (เช่นคืน entity ที่ลบ); ใช้ warn พอ

→ CI กรอง spec ผิดมาตรฐาน


17. ⚠️ Common Pitfalls

Doc เขียนทีหลัง (มัก outdated)annotation + auto-generate
ไม่มี exampleexample ทุก field สำคัญ
Description ว่างmeaningful description
ไม่ document error codedocument ทุก response รวม 4xx
Sample = plain text "TODO"actual example data
Public endpoint ลึก ๆ ไม่มี docdoc ทุก public endpoint
ไม่ versioning ใน doc/v1, /v2 clear
Doc + code not in syncsource of truth = 1 ที่ (code หรือ spec)

18. Best Practices Summary

สรุปแนวทางทำ API documentation ที่ดีทั้งบท — ให้ contract เป็น source of truth, auto-generate doc, ใส่ example ทุกที่, มี changelog, generate client, lint ใน CI ทำตามเช็กลิสต์นี้แล้ว doc จะมีคุณภาพและไม่ outdated:

  1. API contract = code — OpenAPI ที่ generated หรือ hand-written
  2. Auto-generate doc — springdoc
  3. Example everywhere — request + response
  4. Changelog — note breaking + deprecation
  5. Generate client — TypeScript / Java สำหรับ consumer
  6. Mock server — Prism for testing
  7. CI lint — Spectral check spec quality
  8. Interactive try-it-out — Swagger UI
  9. Test from spec — Schemathesis, Dredd

19. Checkpoint

ลงมือทำเพื่อให้เข้าใจ OpenAPI จริง — แบบฝึกหัดนี้ให้คุณเพิ่ม springdoc ลง Spring Boot, generate TypeScript client, lint spec ด้วย Spectral และตั้ง mock server ทำครบจะเห็นพลังของ contract-driven development:

🛠️ Checkpoint 5.1 — Add springdoc to Spring Boot

  • Add dependency
  • Add @Operation, @Schema annotations
  • Open Swagger UI
  • Try-it-out a few endpoints

🛠️ Checkpoint 5.2 — Generate TS Client

  • openapi-typescript from /v3/api-docs
  • ใช้ใน React project
  • Compare ก่อน/หลัง: manual interface vs generated

🛠️ Checkpoint 5.3 — Lint with Spectral

  • Install Spectral
  • Lint your spec
  • Fix issues — operation-description, no-untitled, etc.

🛠️ Checkpoint 5.4 — Mock Server

  • Run Prism: prism mock openapi.yaml
  • Frontend dev → API mock — develop independently

🛠️ Checkpoint 5.5 — Contract-First

  • Design new feature (e.g., user search):
    • Write OpenAPI spec first
    • Review with imaginary frontend
    • Generate stubs
    • Implement

20. สรุปบท

OpenAPI 3.1 = standard ปี 2026 — single source of truth
Springdoc — auto-generate OpenAPI จาก Spring Boot — เปิด /swagger-ui
✅ Annotations: @Operation, @Schema, @Parameter, @ApiResponse
✅ Generate client: TypeScript (openapi-typescript), Java/Python (openapi-generator)
✅ Mock server: Prism — frontend ทำงานก่อน backend ได้
✅ Lint: Spectral — CI check spec quality
Contract-first design — spec ก่อน → review → implement parallel
✅ Documentation includes: example, edge case, side effect, changelog
✅ Public APIAPI portal (Readme, Mintlify, Stoplight)


← บทที่ 4 | บทที่ 6 → GraphQL + gRPC