DEV Community

Cover image for วิธีออกแบบ API จาก CLI
Thanawat Wongchai
Thanawat Wongchai

Posted on • Originally published at apidog.com

วิธีออกแบบ API จาก CLI

บทช่วยสอนการออกแบบ API จำนวนมากเริ่มจากการเปิด GUI ลากสคีมาลงบนผืนผ้าใบ และคลิกเพิ่มฟิลด์ วิธีนี้ใช้ได้ แต่ไม่เหมาะกับทีมที่เก็บสัญญา API ไว้ใน Git ตรวจผ่าน Pull Request และรันใน CI หากกระบวนการ deploy ของคุณเริ่มจากเทอร์มินัล การออกแบบ API ก็ควรทำแบบเดียวกัน: ใช้ไฟล์ข้อความ คำสั่งที่ทำซ้ำได้ และสคริปต์ที่รันอัตโนมัติได้

ลองใช้ Apidog วันนี้

การออกแบบ API ผ่าน CLI ทำให้คุณสร้างสัญญา API, ตรวจสอบไวยากรณ์ตาม style guide, รวมไฟล์ และสร้าง server stub หรือ SDK ได้โดยไม่ต้องออกจาก shell ทุกขั้นตอนนำไปใส่ใน CI ได้ และเพื่อนร่วมทีมหรือ AI agent สามารถรันคำสั่งเดียวกับที่คุณใช้ได้โดยไม่ต้องเดาว่าคุณคลิกอะไรใน GUI

บทความนี้ครอบคลุม 2 แนวทาง:

  1. แนวทางโอเพนซอร์ส: เขียน OpenAPI, lint ด้วย Spectral, bundle ด้วย Redocly CLI และสร้างโค้ดด้วย openapi-generator
  2. แนวทาง Apidog CLI: จัดการ schema, endpoint และ authentication ภายในโปรเจกต์เดียวจากเทอร์มินัล

หากต้องการทบทวนพื้นฐานก่อนเริ่ม อ่าน วิธีออกแบบ API และ การออกแบบ REST API

หากจะใช้ Apidog ให้ติดตั้ง CLI และล็อกอินก่อน โดยดูขั้นตอนเพิ่มเติมได้จากคู่มือการติดตั้ง Apidog CLI และคู่มือ Apidog CLI ฉบับสมบูรณ์

npm install -g apidog-cli
apidog login --with-token <YOUR_ACCESS_TOKEN>
Enter fullscreen mode Exit fullscreen mode

เส้นทางโอเพนซอร์สทั่วไป: สร้าง, ตรวจสอบไวยากรณ์, รวม, สร้าง

แนวทางนี้ใช้เครื่องมือแยกกันเป็นขั้นตอน คุณเก็บ OpenAPI definition ไว้ใน repository และให้ CI รัน lint, bundle และ generate ตามลำดับ นี่คือรูปแบบของ เวิร์กโฟลว์การออกแบบ API แบบ Git-native

1. สร้างเอกสาร OpenAPI

เริ่มจากไฟล์ openapi.yaml ปกติ ไม่ต้องใช้ตัวแก้ไขเฉพาะทาง ตัวอย่างขั้นต่ำสำหรับ Orders API:

openapi: 3.0.3
info:
  title: Orders API
  version: 1.0.0

paths:
  /orders/{orderId}:
    get:
      operationId: getOrder
      parameters:
        - name: orderId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: An order
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Order'

components:
  schemas:
    Order:
      type: object
      required: [id, status]
      properties:
        id:
          type: string
        status:
          type: string
          enum: [pending, shipped, delivered]
Enter fullscreen mode Exit fullscreen mode

เมื่อ API มีขนาดใหญ่ขึ้น ให้แยก schema, path และ response เป็นหลายไฟล์ แล้วเชื่อมด้วย $ref ตัวอย่างโครงสร้าง:

.
├── openapi.yaml
├── paths/
│   └── orders.yaml
└── schemas/
    └── order.yaml
Enter fullscreen mode Exit fullscreen mode

แนวทางนี้ช่วยให้แต่ละไฟล์อ่านง่ายและ review ได้ง่ายขึ้น แต่ต้อง bundle ก่อนส่งต่อให้เครื่องมือปลายน้ำ

2. ตรวจสอบไวยากรณ์ด้วย Spectral

OpenAPI ที่เขียนด้วยมืออาจมีจุดผิดพลาด เช่น ลืม operationId, ไม่มี response ที่บันทึกไว้ หรือใช้รูปแบบการตั้งชื่อไม่สอดคล้องกัน ใช้ Spectral เพื่อตรวจหาปัญหาเหล่านี้ก่อน merge

npm install -g @stoplight/spectral-cli
spectral lint openapi.yaml
Enter fullscreen mode Exit fullscreen mode

Spectral จะแสดงไฟล์ หมายเลขบรรทัด ระดับความรุนแรง และกฎที่ละเมิด คุณจึงสามารถตั้ง CI ให้ล้มเหลวทันทีเมื่อ lint ไม่ผ่านได้

หากต้องการทางเลือกอื่น ใช้ Redocly CLI หรือ vacuum ได้เช่นกัน โดย vacuum เป็น linter ที่เข้ากันได้กับ Spectral และทำงานได้รวดเร็ว

สิ่งสำคัญคือแยกหน้าที่ให้ชัดเจน:

  • Linting: ตรวจ style guide และกฎ OpenAPI
  • Bundling: รวม $ref เป็นไฟล์เดียว
  • Code generation: สร้าง server stub หรือ SDK

3. รวมไฟล์ด้วย Redocly CLI

เมื่อ OpenAPI ถูกแยกเป็นหลายไฟล์ เครื่องมือสร้างโค้ดและระบบเอกสารจำนวนมากต้องการไฟล์เดียวที่ self-contained ใช้ redocly bundle เพื่อแก้ $ref และรวมเป็นไฟล์เดียว

npm install -g @redocly/cli

mkdir -p dist
redocly bundle openapi.yaml -o dist/openapi.bundled.yaml
Enter fullscreen mode Exit fullscreen mode

จากนั้นใช้ไฟล์ dist/openapi.bundled.yaml เป็น artifact กลางสำหรับขั้นตอนต่อไป

Redocly ยังรองรับ lint และ preview เอกสารด้วย ดูคำสั่งทั้งหมดได้จากเอกสาร Redocly CLI

4. สร้าง server stub หรือ SDK ด้วย openapi-generator

หลังจาก lint และ bundle ผ่านแล้ว ให้สร้างโค้ดจาก OpenAPI definition ได้ทันที

npm install -g @openapitools/openapi-generator-cli

openapi-generator-cli generate \
  -i dist/openapi.bundled.yaml \
  -g spring \
  -o ./server
Enter fullscreen mode Exit fullscreen mode

เปลี่ยน generator ด้วย flag -g ตาม stack ที่คุณใช้ เช่น:

# Python Flask server
openapi-generator-cli generate \
  -i dist/openapi.bundled.yaml \
  -g python-flask \
  -o ./server

# Go server
openapi-generator-cli generate \
  -i dist/openapi.bundled.yaml \
  -g go-server \
  -o ./server
Enter fullscreen mode Exit fullscreen mode

เส้นทางโอเพนซอร์สจึงมี 4 ขั้นตอนหลัก:

# 1. เขียน OpenAPI
$EDITOR openapi.yaml

# 2. ตรวจ style และข้อผิดพลาด
spectral lint openapi.yaml

# 3. Bundle ทุก $ref
redocly bundle openapi.yaml -o dist/openapi.bundled.yaml

# 4. สร้างโค้ด
openapi-generator-cli generate \
  -i dist/openapi.bundled.yaml \
  -g spring \
  -o ./server
Enter fullscreen mode Exit fullscreen mode

ข้อดีคือควบคุมทุกส่วนได้เต็มที่ ข้อแลกเปลี่ยนคือคุณต้องดูแล file layout, linter configuration, bundling และ generator configuration เอง

เส้นทาง Apidog CLI: การออกแบบในโปรเจ็กต์เดียว

อีกแนวทางคือเก็บ schema, endpoint, mock และ authentication ไว้ในโปรเจ็กต์เดียว แล้วจัดการทั้งหมดจากเทอร์มินัล

apidog-cli ไม่ได้เป็นเพียง test runner แต่เป็น CLI สำหรับจัดการทรัพยากรของโปรเจ็กต์ โดยมี command group เช่น:

  • schema สำหรับ data model
  • endpoint สำหรับ API operation
  • folder สำหรับจัดกลุ่ม endpoint
  • security-scheme สำหรับ authentication
  • import และ export สำหรับแลกเปลี่ยน definition
  • mock สำหรับ mock API

ข้อควรเข้าใจ: Apidog ไม่ได้ทำหน้าที่ lint OpenAPI หรือบังคับใช้ style guide หากต้องการตรวจมาตรฐาน OpenAPI ให้คง Spectral หรือ vacuum ไว้ใน pipeline ของคุณ Apidog เป็นผลิตภัณฑ์เชิงพาณิชย์ที่มี free tier โดยเน้นการจัดการทรัพยากร API แบบรวมศูนย์ ดูรายละเอียดการเปรียบเทียบได้จากทางเลือก Swagger สำหรับการออกแบบและทดสอบ API

ทุกคำสั่งของ Apidog CLI คืนค่า JSON แบบมีโครงสร้าง และ response ส่วนใหญ่มี agentHints.nextSteps เพื่อแนะนำคำสั่งถัดไป ใช้ --help กับทุกคำสั่งเพื่อดู flag ที่รองรับ

1. กำหนดโมเดลข้อมูลด้วย apidog schema

เริ่มจาก schema ที่นำกลับมาใช้ซ้ำได้ เช่น Order ซึ่งทำหน้าที่คล้าย components/schemas ใน OpenAPI

apidog schema --help
apidog schema create --project <PROJECT_ID>
Enter fullscreen mode Exit fullscreen mode

เนื่องจาก output เป็น JSON คุณสามารถใช้ jq ดึง ID เพื่อนำไปใช้ในสคริปต์ขั้นถัดไปได้

apidog schema create --project <PROJECT_ID> | jq '.data.id'
Enter fullscreen mode Exit fullscreen mode

หากมี OpenAPI อยู่แล้ว ให้นำเข้าแทนการสร้างใหม่ทีละส่วน:

apidog import --project <PROJECT_ID> --file openapi.yaml
Enter fullscreen mode Exit fullscreen mode

apidog import รองรับ OpenAPI 3.x, Swagger 2.0, Postman และรูปแบบ Apidog จึงเหมาะสำหรับย้าย definition เดิมเข้ามาเป็นโปรเจ็กต์จริงในขั้นตอนเดียว

2. กำหนด endpoint ด้วย apidog endpoint

เมื่อมี schema แล้ว ให้สร้างหรือแก้ไข endpoint ภายในโปรเจ็กต์

apidog endpoint --help

# ดู endpoint ที่มีอยู่
apidog endpoint list --project <PROJECT_ID>

# สร้าง endpoint
apidog endpoint create --project <PROJECT_ID>
Enter fullscreen mode Exit fullscreen mode

การแสดงรายการ endpoint เป็น JSON ทำให้ตรวจสอบผ่านสคริปต์ได้ เช่น เปรียบเทียบ endpoint ระหว่าง branch หรือเช็กว่ามี response ที่คาดหวังครบหรือไม่

ใช้ folder จัดกลุ่ม endpoint ที่เกี่ยวข้องกัน เพื่อให้โปรเจ็กต์ยังนำทางได้ง่ายเมื่อ API เติบโตขึ้น

3. กำหนด authentication ด้วย apidog security-scheme

Authentication เป็นส่วนหนึ่งของ API contract ควรกำหนดให้ชัดเจนตั้งแต่ต้น ไม่ใช่เพิ่มทีหลัง

apidog security-scheme --help
apidog security-scheme list --project <PROJECT_ID>
Enter fullscreen mode Exit fullscreen mode

คุณสามารถกำหนดรูปแบบ authentication เช่น API key, bearer token หรือ OAuth 2.0 ที่ระดับโปรเจ็กต์ แล้วให้ endpoint อ้างอิง scheme เดียวกัน

แนวทางนี้สอดคล้องกับ components/securitySchemes ของ OpenAPI และช่วยลดปัญหาการประกาศ auth ซ้ำในทุก operation

4. ตรวจสอบ resource definition ด้วย apidog cli-schema validate

ก่อน commit หรือ apply resource definition ใน CI ให้ตรวจไฟล์กับ schema ที่ CLI คาดหวังก่อน

apidog cli-schema --help
apidog cli-schema validate --file resource.json
Enter fullscreen mode Exit fullscreen mode

เพิ่มคำสั่งนี้เป็น validation step ก่อนนำ resource ไปใช้จริง:

apidog cli-schema validate --file resource.json
Enter fullscreen mode Exit fullscreen mode

หากคำสั่งคืนค่า exit code ที่ไม่ใช่ศูนย์ CI ควรหยุดทันที

โปรดแยกความหมายของ validation สองแบบนี้:

เครื่องมือ ตรวจอะไร
apidog cli-schema validate โครงสร้าง resource definition สำหรับ CLI
spectral lint style guide และกฎ OpenAPI

apidog cli-schema validate ไม่ใช่ OpenAPI linter ดังนั้นหากต้องการ enforce กฎ API design ให้ใช้ Spectral หรือ vacuum เพิ่มเติม

5. ส่งออกกลับเป็น OpenAPI

แม้ออกแบบและจัดการ API ภายใน Apidog คุณยังส่งออกเป็นมาตรฐาน OpenAPI เพื่อใช้กับเครื่องมืออื่นได้

apidog export \
  --project <PROJECT_ID> \
  --format openapi \
  -o dist/openapi.yaml
Enter fullscreen mode Exit fullscreen mode

หลังจากนั้นคุณสามารถนำไฟล์ที่ export ไปใช้กับ workflow เดิมได้ทันที:

# Lint OpenAPI ที่ export ออกมา
spectral lint dist/openapi.yaml

# Bundle สำหรับเครื่องมือปลายน้ำ
redocly bundle dist/openapi.yaml -o dist/openapi.bundled.yaml

# สร้าง server stub
openapi-generator-cli generate \
  -i dist/openapi.bundled.yaml \
  -g spring \
  -o ./server
Enter fullscreen mode Exit fullscreen mode

ดังนั้น Apidog CLI และเครื่องมือโอเพนซอร์สไม่จำเป็นต้องเลือกอย่างใดอย่างหนึ่ง การ export OpenAPI คือสะพานเชื่อมระหว่างสองแนวทาง

เชื่อมต่อเข้ากับ CI

CLI เหมาะกับ CI เพราะทุกคำสั่งมี exit code และ output ที่อ่านได้จากสคริปต์ ตัวอย่าง pipeline ขั้นต่ำ:

# ล้มเหลวเมื่อมีข้อผิดพลาดด้านสไตล์ OpenAPI
spectral lint openapi.yaml

# ตรวจ resource definition ก่อนนำไปใช้
apidog cli-schema validate --file resource.json

# รวมเป็น artifact เดียวสำหรับขั้นตอนปลายน้ำ
redocly bundle openapi.yaml -o dist/openapi.bundled.yaml
Enter fullscreen mode Exit fullscreen mode

ตัวอย่าง GitHub Actions:

name: Validate API Contract

on:
  pull_request:
    paths:
      - "openapi.yaml"
      - "paths/**"
      - "schemas/**"
      - "resource.json"

jobs:
  validate-api:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Install API tooling
        run: |
          npm install -g @stoplight/spectral-cli
          npm install -g @redocly/cli
          npm install -g apidog-cli

      - name: Lint OpenAPI
        run: spectral lint openapi.yaml

      - name: Validate Apidog resource definition
        run: apidog cli-schema validate --file resource.json

      - name: Bundle OpenAPI
        run: |
          mkdir -p dist
          redocly bundle openapi.yaml -o dist/openapi.bundled.yaml
Enter fullscreen mode Exit fullscreen mode

JSON output ของ Apidog และ agentHints.nextSteps ยังช่วยให้ AI coding agent ทำงานต่อเนื่องได้ง่ายขึ้น: agent อ่าน output, เลือกคำสั่งถัดไป และรันใน shell โดยไม่ต้องพึ่ง GUI

ปัญหาที่พบบ่อย

การแยกไฟล์ทำให้เครื่องมือปลายน้ำใช้งานไม่ได้

ไฟล์ที่แยกด้วย $ref เหมาะกับการอ่านและ review แต่ code generator หรือ documentation tool หลายตัวต้องการไฟล์เดียว

ให้ bundle ทุกครั้งก่อน generate หรือ publish:

redocly bundle openapi.yaml -o dist/openapi.bundled.yaml
Enter fullscreen mode Exit fullscreen mode

คาดหวังให้ Apidog lint OpenAPI

Apidog จัดการทรัพยากรของโปรเจ็กต์ ไม่ได้บังคับ style guide หรือรายงานการละเมิดกฎ OpenAPI

ใช้ Spectral หรือ vacuum สำหรับ linting:

spectral lint openapi.yaml
Enter fullscreen mode Exit fullscreen mode

อย่าสับสนระหว่าง apidog cli-schema validate กับ OpenAPI linting เพราะคำสั่งแรกตรวจ resource structure ไม่ใช่ style ของ OpenAPI

ลืมนำเข้า definition เดิมก่อนแก้ไข

หาก API มีอยู่แล้วในไฟล์ OpenAPI ให้ import ก่อนเริ่มแก้ไขผ่าน CLI

apidog import --project <PROJECT_ID> --file openapi.yaml
Enter fullscreen mode Exit fullscreen mode

การเริ่มจากโปรเจ็กต์ว่างแล้วคาดหวังว่า endpoint เดิมจะมีอยู่แล้วมักทำให้เกิดความสับสน

กำหนด authentication ซ้ำในแต่ละ endpoint

กำหนด security-scheme ที่ระดับโปรเจ็กต์หนึ่งครั้ง แล้วให้ endpoint อ้างอิง scheme เดียวกัน วิธีนี้ช่วยลด contract drift และทำให้การเปลี่ยนแปลง authentication ทำได้จากจุดเดียว

สรุป

การออกแบบ API ผ่าน CLI เปลี่ยนงานที่ต้องคลิกหลายครั้งให้เป็นคำสั่งที่ทำซ้ำได้ ตรวจสอบได้ และรันใน CI ได้

หากต้องการควบคุมเต็มรูปแบบ ให้ใช้แนวทางโอเพนซอร์ส:

  1. เขียน OpenAPI
  2. Lint ด้วย Spectral
  3. Bundle ด้วย Redocly
  4. Generate ด้วย openapi-generator

หากต้องการจัดการ schema, endpoint และ authentication ในโปรเจ็กต์เดียวจากเทอร์มินัล ให้ใช้ Apidog CLI แล้ว export OpenAPI เมื่อต้องส่งต่อ artifact ไปยัง tooling อื่น

เลือก workflow ที่เหมาะกับทีมของคุณ หากคุณอยู่ใน Git และมีเครื่องมือเฉพาะทางอยู่แล้ว ให้ใช้ต่อไปได้ และเพิ่ม apidog export เมื่อต้องการ OpenAPI artifact ที่พกพาได้ หากไม่ต้องการดูแลการเชื่อมต่อระหว่างหลายเครื่องมือ ให้ดาวน์โหลด Apidog ติดตั้ง CLI และออกแบบ API ถัดไปจากเทอร์มินัลได้ทันที

Top comments (0)