Cách Sử Dụng Discriminator Để Đối Sánh Cấu Trúc Tham Số Khác Nhau Theo Loại Khi Thiết Kế API Trong Apidog

Oliver Kingsley

Oliver Kingsley

6 tháng 11 2025

Cách Sử Dụng Discriminator Để Đối Sánh Cấu Trúc Tham Số Khác Nhau Theo Loại Khi Thiết Kế API Trong Apidog

Trong bài viết trước của chúng tôi "Phải làm gì khi API có nhiều cấu trúc tham số", chúng tôi đã thảo luận rằng khi một API yêu cầu các cấu trúc tham số khác nhau, bạn có thể sử dụng oneOf, anyOf, hoặc allOf trong Apidog để định nghĩa chúng.

Sau khi bạn đã thiết lập các cấu trúc tham số bằng cách sử dụng các thành phần lược đồ này, và các tham số của bạn bao gồm một trường xác định kiểu dữ liệu, bạn có thể làm cho tài liệu rõ ràng hơn nữa bằng cách sử dụng tính năng discriminator từ đặc tả OpenAPI để phân biệt giữa các lược đồ một cách trực quan hơn.

Discriminator là gì?

Trong OpenAPI, vai trò của discriminator là triển khai "đa hình" từ lập trình hướng đối tượng.

Nói một cách đơn giản, nó sử dụng một thuộc tính chung và giá trị duy nhất của thuộc tính đó để chỉ rõ lược đồ cụ thể nào trong danh sách oneOf hoặc anyOf nên được sử dụng.

Ví dụ, trong một cửa hàng thú cưng, chúng ta cần sử dụng một lược đồ để mô tả thú cưng. (Và mèo và chó có các thuộc tính khác nhau.)

Lược đồ cho chó là:

{

    "name": "Hotdog",

    "age": 3,

    "weight": 25.5,

    "petType": "dog",

    "breed": "Golden Retriever",

    "isVaccinated": true,

    "walkingSchedule": "Morning and Evening",

    "favoriteToys": ["Frisbee", "Tennis Ball"],

    "trainingLevel": "Intermediate"

}

Lược đồ cho mèo là:

{

    "name": "Meow",

    "age": 2,

    "weight": 4.2,

    "petType": "cat",

    "isVaccinated": true,

    "isIndoor": true,

    "litterBoxType": "Enclosed",

    "scratchingPostHeight": 120,

    "favoriteSleepingSpot": "Balcony"

}

Như bạn có thể thấy, mặc dù cả hai lược đồ đều có các trường chung như petType, name, age, v.v., chó có các trường đặc trưng như breed, walkingSchedule, v.v., trong khi mèo có các trường đặc trưng như isIndoor, litterBoxType, v.v.

Nếu bạn chỉ sử dụng oneOf để định nghĩa các lược đồ này khi thiết kế tài liệu API của mình, tài liệu có thể về mặt kỹ thuật phân biệt giữa các lược đồ dogcat. Tuy nhiên, sự tương ứng của từng loại không rõ ràng lắm. Người đọc phải chuyển đổi giữa hai tab lược đồ để so sánh chúng, điều này trở nên khó hiểu khi có nhiều tham số.

sử dụng oneOf để định nghĩa nhiều lược đồ

Bằng cách thêm một discriminator, tài liệu sẽ hiển thị một menu thả xuống, nơi người đọc có thể chọn giá trị của petType (dog hoặc cat). Sau khi được chọn, trang sẽ tự động hiển thị lược đồ chính xác với các trường liên quan. Điều này loại bỏ nhu cầu so sánh nhiều tab và làm cho sự khác biệt giữa mỗi lược đồ rõ ràng hơn nhiều.

discriminator làm cho các lược đồ rõ ràng hơn

Một discriminator thường được sử dụng cùng với oneOf hoặc anyOf. oneOf định nghĩa các lược đồ đối tượng có thể có, và discriminator cho trình phân tích biết cách xác định lược đồ nào sẽ áp dụng dựa trên loại đã chọn.

Điều này làm cho các đối tượng phức tạp rõ ràng hơn và giúp các công cụ tự động phân biệt các loại khi hiển thị tài liệu hoặc tạo mã.

Các thuộc tính cấu hình của discriminator

Một discriminator chứa hai thuộc tính chính:

Ví dụ cấu hình trong OpenAPI:

discriminator:
  propertyName: petType
  mapping:
    dog: '#/components/schemas/Dog'
    cat: '#/components/schemas/Cat'

Cấu hình Discriminator trong Apidog

Apidog hỗ trợ cấu hình discriminator theo hai cách:

  1. GUI + JSON Schema
  2. Nhập trực tiếp các đặc tả OpenAPI

Phương pháp 1: GUI + JSON Schema

Đầu tiên, tạo các lược đồ trong Apidog, chẳng hạn như DogCat:

định nghĩa các lược đồ trong Apidog

Mở endpoint nơi bạn muốn sử dụng các lược đồ này và đi đến trình chỉnh sửa nội dung yêu cầu hoặc phản hồi.

Chọn trường bạn muốn định nghĩa là một thành phần lược đồ và chọn Cài đặt nâng caoThành phần lược đồoneOf.

Trong oneOf, tham chiếu các lược đồ bạn cần, chẳng hạn như DogCat.

tham chiếu các lược đồ cho các thành phần lược đồ oneOf

Bây giờ bạn đã định nghĩa nhiều lược đồ có thể thông qua oneOf. Tiếp theo, bạn cần thêm discriminator để chỉ định cách phân biệt các lược đồ này. Nhấp vào JSON Schema để chuyển sang chế độ mã:

trình chỉnh sửa JSON Schema trong Apidog

Thêm cấu hình discriminator vào vị trí thích hợp (cùng cấp với oneOf), ví dụ:

"discriminator": {
    "propertyName": "petType",
    "mapping": {
        "dog": "#/definitions/190704823",
        "cat": "#/definitions/190704706"
    }
}

Các giá trị trong mapping, chẳng hạn như #/definitions/190704823, là các ID duy nhất được Apidog tạo nội bộ cho các lược đồ. Bạn có thể tìm thấy đường dẫn definitions tương ứng cho mỗi lược đồ trong bảng cấu hình JSON Schema.

bảng cấu hình JSON Schema trong Apidog

Sau khi cấu hình hoàn tất, hãy lưu lại. Trong tài liệu API, bạn có thể chuyển đổi các loại đối tượng một cách thông minh dựa trên giá trị của trường petType.

Phương pháp 2: Nhập trực tiếp các đặc tả OpenAPI

Đây là một cách tiếp cận tiêu chuẩn hơn, đặc biệt phù hợp cho các nhóm quen với quy trình làm việc "thiết kế trước".

Viết các đặc tả OpenAPI của bạn có kèm discriminator, sau đó nhập chúng vào Apidog.

Ví dụ, trong các đặc tả OpenAPI, định nghĩa của discriminator như sau:

Pet:
  oneOf:
    - $ref: '#/components/schemas/Dog'
    - $ref: '#/components/schemas/Cat'
  discriminator:
    propertyName: petType
    mapping:
      dog: '#/components/schemas/Dog'
      cat: '#/components/schemas/Cat'

Định nghĩa này nêu rõ:

Các đặc tả OpenAPI hoàn chỉnh như sau:

openapi: 3.0.3
info:
  title: Pet Shop API
  version: 1.0.0

components:
  schemas:
    Dog:
      type: object
      properties:
        petType:
          type: string
          enum: [dog]
        name:
          type: string
        age:
          type: integer
        weight:
          type: number
        breed:
          type: string
        isVaccinated:
          type: boolean
        walkingSchedule:
          type: string
        favoriteToys:
          type: array
          items:
            type: string
        trainingLevel:
          type: string
      required:
        - petType
        - name
        - age

    Cat:
      type: object
      properties:
        petType:
          type: string
          enum: [cat]
        name:
          type: string
        age:
          type: integer
        weight:
          type: number
        isVaccinated:
          type: boolean
        isIndoor:
          type: boolean
        litterBoxType:
          type: string
        scratchingPostHeight:
          type: integer
        favoriteSleepingSpot:
          type: string
      required:
        - petType
        - name
        - age

    Pet:
      oneOf:
        - $ref: '#/components/schemas/Dog'
        - $ref: '#/components/schemas/Cat'
      discriminator:
        propertyName: petType
        mapping:
          dog: '#/components/schemas/Dog'
          cat: '#/components/schemas/Cat'

paths:
  /pets:
    get:
      summary: Get pet information
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Pet'

Sau khi hoàn thành các đặc tả OpenAPI, sử dụng tính năng import trong Apidog. Apidog sẽ phân tích tất cả các đặc tả, tự động tạo các lược đồ và endpoint tương ứng, đồng thời nhận diện chính xác cấu hình discriminator (enum được thêm vào đây để khóa các giá trị tham số).

nhập OpenAPI để thêm discriminator nhằm phân biệt nhiều lược đồ

Câu hỏi thường gặp

1. Khi nào nên sử dụng Discriminator?

Bạn chỉ nên sử dụng discriminator khi endpoint của bạn đã bao gồm một trường xác định các lược đồ. Trong ví dụ trên, trường petType tồn tại trong thiết kế API và được sử dụng để phân biệt giữa các loại thú cưng.

discriminator chỉ đơn giản cho các công cụ biết cách chọn lược đồ chính xác dựa trên giá trị của trường đó.

Nếu endpoint của bạn không bao gồm một trường xác định loại như vậy, thì discriminator không phù hợp—chỉ cần sử dụng oneOf là đủ.

Ngoài ra, nếu lược đồ của bạn đơn giản hoặc chỉ có một vài biến thể, bạn có thể không cần đến discriminator.

2. Discriminator có bắt buộc phải dùng với oneOf không?

Có. Một discriminator phải được sử dụng cùng với oneOf, anyOf, hoặc allOf. Nó không thể tự định nghĩa các lược đồ—nó chỉ giải thích cách phân biệt giữa nhiều lược đồ có thể có.

Kết luận

discriminator là một tính năng tùy chọn trong đặc tả OpenAPI được sử dụng để nâng cao trải nghiệm người dùng của oneOf/anyOf/allOf.

Khi các đặc tả endpoint của bạn đã chứa các trường được sử dụng để xác định loại, bạn có thể cấu hình discriminator trong Apidog để làm cho tài liệu API rõ ràng và thông minh hơn.

Tất nhiên, nếu bạn thấy việc cấu hình phiền phức hoặc lược đồ tương đối đơn giản, bạn hoàn toàn có thể chỉ sử dụng thành phần lược đồ như oneOf.

Thực hành thiết kế API trong Apidog

Khám phá cách dễ dàng hơn để xây dựng và sử dụng API