โหมดมืด
บทที่ 5 — OpenAPI + Documentation
หลังจบบท คุณจะ:
- เขียน 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 | คืออะไร |
|---|---|
| None | code คือ doc 😱 |
| Markdown | manual, sync ยาก |
| Postman collection | usable, manual |
| OpenAPI spec | machine-readable, auto-generate doc + client |
| Interactive Doc | Swagger UI, try-it-out |
| API Portal | full 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 → เปิด:
- http://localhost:8080/swagger-ui/index.html ← Swagger UI
- http://localhost:8080/v3/api-docs ← OpenAPI JSON
- http://localhost:8080/v3/api-docs.yaml ← OpenAPI YAML
ไม่ต้องเขียน 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 บริษัทใหม่ ๆ ย้ายไป Scalarhtml
<!-- ใช้ 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.tsts
// 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-fetchts
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 URLBruno = 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 librariesTools:
- 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.yamlmy-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 |
| ไม่มี example | example ทุก field สำคัญ |
| Description ว่าง | meaningful description |
| ไม่ document error code | document ทุก response รวม 4xx |
| Sample = plain text "TODO" | actual example data |
| Public endpoint ลึก ๆ ไม่มี doc | doc ทุก public endpoint |
| ไม่ versioning ใน doc | /v1, /v2 clear |
| Doc + code not in sync | source 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:
- API contract = code — OpenAPI ที่ generated หรือ hand-written
- Auto-generate doc — springdoc
- Example everywhere — request + response
- Changelog — note breaking + deprecation
- Generate client — TypeScript / Java สำหรับ consumer
- Mock server — Prism for testing
- CI lint — Spectral check spec quality
- Interactive try-it-out — Swagger UI
- 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,@Schemaannotations - Open Swagger UI
- Try-it-out a few endpoints
🛠️ Checkpoint 5.2 — Generate TS Client
openapi-typescriptfrom/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 API → API portal (Readme, Mintlify, Stoplight)