Kiểm thử API dựa trên dữ liệu với Apidog CLI: Duyệt qua CSV và JSON

Một hướng dẫn thực tế về cờ -d của Apidog CLI: chạy một kịch bản kiểm thử từ một tập dữ liệu CSV, JSON hoặc đã lưu trữ, gỡ lỗi liên kết và chạy các bài kiểm thử dựa trên dữ liệu trong CI.

INEZA Felin-Michel

INEZA Felin-Michel

16 tháng 6 2026

Kiểm thử API dựa trên dữ liệu với Apidog CLI: Duyệt qua CSV và JSON

Apidog cho doanh nghiệp

Triển khai tại chỗ

SSO & RBAC

Tuân thủ SOC 2

Khám phá Apidog Enterprise

Bạn đã xây dựng một kịch bản kiểm thử vững chắc cho điểm cuối thanh toán của mình. Nó chuỗi ba yêu cầu, xác nhận trên từng phản hồi và luôn vượt qua mỗi khi bạn nhấp vào Chạy. Sau đó, quy trình của bạn cần nó để bao gồm bốn mươi kết hợp đầu vào, lấy dữ liệu từ một tệp mà trưởng nhóm QA của bạn duy trì, và chạy cùng một kịch bản đối với môi trường staging và production với các thông tin xác thực khác nhau. Việc chạy nhấp-và-chọn đã hoạt động trên máy tính xách tay của bạn không chuyển đổi được sang điều đó, và bạn không muốn sao chép kịch bản bốn mươi lần.

Chặng cuối đó là những gì dòng lệnh xử lý. Với Apidog, bạn viết một kịch bản kiểm thử một lần trong trình tạo hình ảnh, sau đó điều khiển nó từ terminal với gói apidog-cli. Cờ biến một kịch bản thành một lần chạy theo dữ liệu là -d, viết tắt của --iteration-data. Nó nhận một tệp CSV, một tệp JSON, hoặc một bộ dữ liệu bạn đã lưu trữ trong dự án Apidog của mình, và nó chạy kịch bản một lần cho mỗi hàng, liên kết các giá trị của mỗi hàng với các biến mà yêu cầu của bạn tham chiếu.

button

Cách cờ -d đọc tệp

Toàn bộ tính năng nằm trong một tùy chọn. Đây là dạng đầy đủ và dạng viết tắt, lấy trực tiếp từ apidog run --help:

-d, --iteration-data <path|testDataId>   Define the data which use for iterations (either JSON or CSV)

<path|testDataId> đó là chi tiết mà hầu hết mọi người thường bỏ qua. Đối số này bị quá tải (overloaded). Truyền một đường dẫn và CLI sẽ đọc một tệp cục bộ từ đĩa. Truyền một ID dữ liệu kiểm thử và CLI sẽ lấy một bộ dữ liệu bạn đã lưu trong dự án Apidog của mình. Cùng một cờ, hai nguồn, và trình chạy sẽ tự động xác định bạn đã cung cấp cái nào.

Dạng tệp cục bộ là điểm khởi đầu phổ biến. Chỉ định nó đến một tệp tương đối so với nơi bạn chạy lệnh:

apidog run --access-token $APIDOG_ACCESS_TOKEN \
  -t 605067 -e 1629989 \
  -d ./test-data/checkout-cases.csv -r cli

CLI mở checkout-cases.csv, đếm số hàng dưới tiêu đề, và chạy kịch bản 605067 một lần cho mỗi hàng. Trên mỗi lần chạy, nó liên kết các cột với các biến tương ứng trong yêu cầu của bạn, thực thi kịch bản, và ghi lại kết quả của lần lặp đó. Bốn mươi hàng, bốn mươi lần chạy, một kịch bản.

Định dạng theo tệp. Cùng một cờ chấp nhận JSON mà không cần thêm tùy chọn nào:

apidog run --access-token $APIDOG_ACCESS_TOKEN \
  -t 605067 -e 1629989 \
  -d ./test-data/checkout-cases.json -r cli

Bạn không cần cho CLI biết bạn đang sử dụng định dạng nào. Nó đọc phần mở rộng và cấu trúc tệp. Điều đó có nghĩa là bạn có thể hoán đổi một tệp CSV bằng một mảng JSON giữa dự án mà không cần thay đổi lệnh, miễn là tên cột và khóa JSON khớp với các biến mà kịch bản của bạn mong đợi.

Những gì CLI mong đợi bên trong mỗi tệp

CSV là định dạng cho các trường hợp dạng bảng, phẳng. Hàng tiêu đề đặt tên cho các biến của bạn. Mỗi hàng bên dưới nó là một lần lặp. Đây là một tệp checkout-cases.csv thực tế cho một điểm cuối giảm giá:

sku,quantity,coupon,expected_status,expected_total
DESK-01,1,SAVE10,200,89.10
DESK-01,0,SAVE10,422,0
CHAIR-09,3,,200,447.00
DESK-01,1,EXPIRED,410,0
GHOST-99,1,SAVE10,404,0

Năm cột trở thành năm biến. Bên trong nội dung yêu cầu, bạn viết {{sku}}{{quantity}}; trong các xác nhận, bạn so sánh phản hồi với {{expected_status}}{{expected_total}}. Trình chạy liên kết chúng theo từng hàng. Ô coupon trống trong hàng thứ ba trở thành một chuỗi rỗng, đó chính xác là trường hợp không có coupon bạn muốn bao phủ.

JSON là định dạng khi các trường hợp của bạn mang cấu trúc lồng nhau mà khó chuyển đổi thành các cột phẳng. Tệp là một mảng các đối tượng, một đối tượng cho mỗi lần lặp:

[
  {
    "label": "valid order, two items",
    "order": {
      "items": [
        { "sku": "DESK-01", "qty": 1 },
        { "sku": "CHAIR-09", "qty": 2 }
      ],
      "shipping": { "country": "US", "method": "ground" }
    },
    "expected_status": 200
  },
  {
    "label": "unshippable country",
    "order": {
      "items": [{ "sku": "DESK-01", "qty": 1 }],
      "shipping": { "country": "ZZ", "method": "ground" }
    },
    "expected_status": 422
  }
]

Bên trong kịch bản, bạn tham chiếu {{order}}{{expected_status}} theo cùng một cách, và trình chạy chuyển các trường của mỗi đối tượng cho lần lặp. Trường label là dành cho bạn. Nó hiển thị trong báo cáo để một lần chạy thất bại đọc là “quốc gia không thể vận chuyển” thay vì “lần lặp 2,” đây là sự khác biệt giữa việc chẩn đoán năm giây và năm phút.

Một vài quy tắc giúp bạn tránh gặp rắc rối với các tệp này trong CI:

Đối với khía cạnh JSONPath của việc viết các xác nhận đọc các giá trị được liên kết này, bài viết thiết lập xác nhận và trích xuất biến từ phản hồi JSON sẽ trình bày chi tiết cú pháp.

Chạy từ một bộ dữ liệu đã lưu trữ thay vì từ một tệp

Dạng thứ hai của -d là dạng không xuất hiện trong hầu hết các hướng dẫn. Thay vì một đường dẫn, bạn truyền một ID dữ liệu kiểm thử:

apidog run --access-token $APIDOG_ACCESS_TOKEN \
  -t 605067 -e 1629989 \
  -d 38291 -r cli

Bây giờ CLI sẽ lấy bộ dữ liệu với ID đó từ dự án Apidog của bạn thay vì đọc một tệp từ đĩa của trình chạy. Điều này hữu ích khi dữ liệu nằm cùng với nhóm, chứ không phải với kho lưu trữ. Trưởng nhóm QA của bạn duy trì bảng trường hợp bên trong Apidog, chỉnh sửa nó trong ứng dụng, và mỗi lần chạy CI sẽ lấy phiên bản hiện tại mà không cần ai cam kết một tệp CSV. Kịch bản, môi trường và dữ liệu đều ở phía máy chủ; lệnh chỉ gọi chúng bằng ID.

Sự đánh đổi là nơi nguồn thông tin đáng tin cậy của bạn nằm. Một tệp CSV được cam kết cung cấp cho bạn một bộ dữ liệu có thể so sánh trong các yêu cầu kéo và được ghim vào cam kết đang được kiểm thử. Một ID dữ liệu kiểm thử được lưu trữ cung cấp cho bạn một bảng chia sẻ duy nhất mà mọi người chỉnh sửa ở một nơi. Cả hai đều không sai. Chọn tệp đã cam kết khi dữ liệu nên di chuyển đồng bộ với mã, và chọn ID đã lưu trữ khi dữ liệu thuộc sở hữu của những người không chạm vào kho lưu trữ.

Chạy ngoại tuyến từ một tệp đã xuất

Có một cách thứ ba để cung cấp dữ liệu cho CLI, và nó thay đổi hình dạng của toàn bộ lệnh. Bạn có thể xuất một trường hợp kiểm thử từ Apidog dưới dạng một tệp độc lập và chạy trực tiếp tệp đó, không có ID kịch bản và không có chuyến khứ hồi mạng để lấy kịch bản:

apidog run ./checkout.apidog-cli.json -r cli,html

Ở đây đối số đầu tiên là một file-source, bản thân trường hợp kiểm thử đã xuất, chứ không phải là một cờ. CLI chạy những gì có trong tệp. Bạn vẫn có thể thêm dữ liệu lặp lại với -d:

apidog run ./checkout.apidog-cli.json -d ./checkout-cases.csv -r cli,junit

Điều này quan trọng trong hai tình huống. Thứ nhất là một trình chạy CI cách ly mạng (air-gapped) hoặc bị khóa không thể truy cập đám mây Apidog để giải quyết ID kịch bản; tệp đã xuất mang theo mọi thứ cần thiết cho lần chạy. Thứ hai là khả năng tái tạo: tệp đã xuất là một ảnh chụp đóng băng của kịch bản tại thời điểm xuất, vì vậy một lần chạy từ nó không bị ảnh hưởng bởi việc ai đó chỉnh sửa kịch bản trong ứng dụng sau này. Để biết cơ chế cài đặt và chạy lần đầu, hướng dẫn cài đặt Apidog CLI bao gồm việc đặt tệp nhị phân vào đúng vị trí, và tài liệu tham khảo Apidog CLI đầy đủ ghi lại mọi cờ trong một bảng.

Ghép nối -d với -n và ghi đè biến

Các lần chạy theo dữ liệu hiếm khi đơn lẻ. Ba cờ thường xuyên được ghép nối với -d.

-n, --iteration-count đặt số lần kịch bản chạy. Khi bạn cung cấp một tệp dữ liệu, số lượng hàng đã điều khiển số lần lặp, vì vậy bạn thường bỏ qua -n và để tệp quyết định. Bạn sử dụng -n chủ yếu khi bạn muốn chạy bảng nhiều hơn một lần, hoặc khi bạn hoàn toàn không chạy với tệp dữ liệu nào, như một bài kiểm thử tải (soak test) lặp lại một kịch bản cố định:

apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 -e 1629989 -n 50 -r cli

--env-var--global-var chèn các cặp key=value tại thời điểm chạy mà không chạm vào môi trường trong dự án của bạn. Đây là cách bạn giữ bí mật và cấu hình riêng cho từng pipeline không nằm trong cả kịch bản và tệp dữ liệu. Tệp dữ liệu chứa các trường hợp kiểm thử; các ghi đè chứa những thứ thay đổi theo từng lần chạy:

apidog run --access-token $APIDOG_ACCESS_TOKEN \
  -t 605067 -e 1629989 \
  -d ./test-data/checkout-cases.csv \
  --env-var "base_url=https://staging.internal" \
  --global-var "api_key=$RUNTIME_API_KEY" \
  -r cli,junit

Sự phân tách này là có chủ ý. Dữ liệu lặp lại là phần của lần chạy giống nhau ở mọi nơi: các trường hợp mà điểm cuối của bạn phải xử lý. Các ghi đè biến là phần thay đổi theo môi trường: host, khóa, người thuê. Giữ thông tin xác thực trong kho bí mật CI của bạn và truyền chúng qua --global-var từ một biến môi trường, như cách $RUNTIME_API_KEY ở trên. Không bao giờ đưa chúng vào CSV, nơi bất kỳ ai có quyền truy cập vào kho lưu trữ đều có thể đọc chúng.

Đọc kết quả từng lần lặp

Một lần chạy theo dữ liệu chỉ hữu ích nếu bạn có thể biết hàng nào bị lỗi. Các cờ báo cáo quyết định những gì bạn nhận được.

apidog run --access-token $APIDOG_ACCESS_TOKEN \
  -t 605067 -e 1629989 \
  -d ./test-data/checkout-cases.csv \
  -r cli,junit --out-dir ./test-reports

-r cli in một bản phân tích dễ đọc cho từng lần lặp ra terminal, đây là những gì bạn quét trong nhật ký xây dựng. -r junit ghi JUnit XML, định dạng mà hầu hết các bảng điều khiển CI phân tích thành cây pass/fail, vì vậy một hàng bị lỗi sẽ hiển thị dưới dạng một kiểm thử bị lỗi được đặt tên thay vì văn bản nhật ký bị ẩn. Bạn cũng có thể truyền htmljson; html cung cấp một báo cáo có thể duyệt để lưu trữ dưới dạng một artifact xây dựng, và json cung cấp đầu ra có cấu trúc thô nếu bạn xử lý sau kết quả. --out-dir kiểm soát nơi các tệp sẽ được lưu để bạn có thể giữ chúng dưới dạng artifact.

Theo mặc định, lần chạy sẽ dừng lại ở xác nhận bị lỗi đầu tiên. Đối với một bảng dữ liệu lớn, đây thường là quyết định sai lầm, vì bạn muốn thấy mọi hàng bị lỗi trong một lần chạy, chứ không phải sửa một lỗi rồi chạy lại để tìm lỗi tiếp theo. Thay đổi hành vi với --on-error:

apidog run --access-token $APIDOG_ACCESS_TOKEN \
  -t 605067 -e 1629989 \
  -d ./test-data/checkout-cases.csv \
  --on-error continue \
  -r cli,junit --out-dir ./test-reports

--on-error continue chạy mọi lần lặp ngay cả khi các lần trước đó thất bại, vì vậy một báo cáo duy nhất cho bạn thấy hàng hai, bảy và mười chín bị lỗi cùng một lúc. Lần chạy vẫn kết thúc với mã thoát khác không nếu có bất kỳ lỗi nào, vì vậy nó vẫn là một cổng kiểm soát thực sự. --on-error end là mặc định dừng nhanh (fast-fail) cho một kiểm tra smoke test nhanh; ignore dành cho bước hiếm khi gặp lỗi đã biết mà bạn không muốn làm gián đoạn lần chạy.

Gỡ lỗi một liên kết không hoạt động một cách im lặng

Chế độ thất bại làm mất nhiều thời gian nhất trong các lần chạy theo dữ liệu không phải là một xác nhận màu đỏ. Đó là một lần chạy màu xanh lá cây nhưng không kiểm thử gì, vì dữ liệu chưa bao giờ được liên kết với yêu cầu. Yêu cầu được gửi với các giá trị rỗng, điểm cuối trả về 200 cho một payload rỗng, và xác nhận tình cờ vượt qua. Mức độ bao phủ trông có vẻ tốt; nhưng không phải vậy.

Khi một lần chạy theo dữ liệu hoạt động kỳ lạ, hãy thêm --verbose:

apidog run --access-token $APIDOG_ACCESS_TOKEN \
  -t 605067 -e 1629989 \
  -d ./test-data/checkout-cases.csv \
  --verbose -r cli

--verbose in toàn bộ yêu cầu và phản hồi cho mỗi lần lặp. Hãy xem nội dung yêu cầu mà trình chạy thực sự đã gửi. Nếu bạn thấy {{sku}} nằm đó chưa được thay thế, hoặc một giá trị trống trong khi ô CSV không trống, liên kết đã bị hỏng. Ba nguyên nhân thông thường, theo thứ tự mức độ thường gặp:

Quy tắc chung: khi các lần lặp vượt qua nhưng bạn nghi ngờ chúng không nên, hãy đọc một yêu cầu chi tiết trước khi bạn tin vào kết quả màu xanh lá cây. Một kiểm thử chạy với đầu vào trống còn tệ hơn là không có kiểm thử nào, bởi vì nó cho bạn biết mọi thứ đều ổn trong khi điểm cuối không được kiểm thử.

Kết nối nó vào CI

Lợi ích là toàn bộ bảng chạy trên mỗi thay đổi mà không cần ai nhấp vào Chạy. Dưới đây là một job GitHub Actions cài đặt CLI và chạy một kịch bản dựa trên CSV trên mỗi yêu cầu kéo:

name: Data-driven API tests
on: [pull_request]

jobs:
  api-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - name: Install Apidog CLI
        run: npm install -g apidog-cli
      - name: Run data-driven scenario
        env:
          APIDOG_ACCESS_TOKEN: ${{ secrets.APIDOG_ACCESS_TOKEN }}
        run: |
          apidog run --access-token $APIDOG_ACCESS_TOKEN \
            -t 605067 -e 1629989 \
            -d ./test-data/checkout-cases.csv \
            --on-error continue \
            -r cli,junit --out-dir ./test-reports
      - name: Upload report
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: api-test-report
          path: ./test-reports

Token đến từ secrets.APIDOG_ACCESS_TOKEN, được thiết lập một lần trong cài đặt kho lưu trữ. --on-error continue thu thập mọi hàng bị lỗi vào một báo cáo thay vì dừng lại ở lỗi đầu tiên. if: always() trên bước tải lên giữ báo cáo ngay cả khi lần chạy thất bại, đó là lúc bạn muốn đọc nó nhất. Hoán đổi đường dẫn CSV bằng một tệp JSON, hoặc bằng một ID dữ liệu kiểm thử đã lưu, và không có gì khác thay đổi.

Ba thao tác tương tự có thể áp dụng cho bất kỳ hệ thống CI nào: cài đặt Node.js và CLI, công khai token dưới dạng biến môi trường, gọi apidog run với -d. GitLab CI, Jenkins, CircleCI, và các hệ thống khác không cần viết lại kiểm thử của bạn cho từng nền tảng. Để biết hướng dẫn sâu hơn về phía Actions, hãy xem tự động hóa kiểm thử API trong GitHub Actions, và để biết toàn bộ các cờ của CLI liên quan đến báo cáo, xử lý lỗi và TLS, hướng dẫn Apidog CLI đầy đủ trình bày mọi tùy chọn.

Một quy trình làm việc có thể mở rộng mà không làm tăng kiểm thử

Bắt đầu với một kịch bản và ba hàng. Xây dựng kịch bản trong ứng dụng với các tham chiếu biến trong yêu cầu và kết quả mong đợi trong các xác nhận. Viết một tệp CSV với một trường hợp thành công, một lỗi đã biết và một trường hợp biên. Chạy cục bộ với -d cho đến khi cả ba lần lặp đều hoạt động.

Sau đó, mở rộng dữ liệu, chứ không phải kịch bản. Mỗi báo cáo lỗi trở thành một hàng mới với đầu ra mong đợi chính xác của nó. Lỗi biến thành một trường hợp hồi quy vĩnh viễn, và bạn không bao giờ viết kiểm thử mới; bạn chỉ thêm một dòng vào một tệp. Sau vài tháng, tệp đó sẽ thu thập tất cả những vấn đề thực tế mà điểm cuối của bạn gặp phải trong môi trường sản xuất.

Cuối cùng, thả lệnh apidog run -d vào CI với --on-error continue và trình báo cáo junit. Bây giờ, một thay đổi làm hỏng hàng coupon đã hết hạn sẽ làm lỗi bản dựng ngay khi nó được đẩy, với một lần lặp được đặt tên chỉ thẳng vào trường hợp bị lỗi. Kịch bản vẫn là một thứ nhỏ, dễ đọc bất kể bảng dữ liệu có lớn đến đâu. Đó là chiến thắng tổng hợp: mức độ bao phủ tăng lên theo dữ liệu nhập, và việc bảo trì không tăng.

Nếu bạn vẫn đang quyết định liệu một trình chạy CLI như thế này có phù hợp với ngăn xếp của bạn so với một framework ưu tiên mã, bài phân tích trong công cụ nào để chọn cho kiểm thử API theo dữ liệu với CSV hoặc JSON so sánh các phương pháp tiếp cận, và Apidog CLI vs Newman bao gồm tương tự dòng lệnh gần nhất từ thế giới Postman.

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

Cờ -d có thể nhận cả đường dẫn tệp và bộ dữ liệu đã lưu trữ không? Cờ -d chấp nhận một trong hai mỗi lần chạy: một đường dẫn CSV hoặc JSON cục bộ, hoặc một ID dữ liệu kiểm thử trỏ đến một bộ dữ liệu đã lưu trong dự án Apidog của bạn. Bạn truyền một giá trị. Sử dụng đường dẫn tệp khi dữ liệu nên được quản lý phiên bản cùng với kho lưu trữ của bạn, và ID đã lưu trữ khi một bảng chia sẻ nằm trong ứng dụng và bạn không muốn cam kết một bản sao.

Tôi có phải cho CLI biết tệp của tôi là CSV hay JSON không? Không. Trình chạy đọc định dạng từ chính tệp, vì vậy cùng một cờ -d xử lý cả hai. Giữ tên cột (CSV) hoặc khóa đối tượng (JSON) khớp với tên biến mà kịch bản của bạn tham chiếu, và bạn có thể chuyển đổi định dạng mà không cần thay đổi lệnh.

Điều gì xảy ra nếu tôi sử dụng -d-n cùng nhau? Số lượng hàng của tệp dữ liệu điều khiển số lần lặp, vì vậy -n thường không cần thiết với -d. Bạn sử dụng -n khi bạn muốn lặp lại một lần chạy mà không có tệp dữ liệu, như một bài kiểm thử tải (soak test), hoặc khi bạn đặc biệt muốn chạy toàn bộ bảng nhiều hơn một lần.

Tại sao lần chạy theo dữ liệu của tôi vượt qua mà không kiểm thử gì? Nguyên nhân phổ biến nhất là một liên kết chưa bao giờ xảy ra: tên cột không khớp với tên biến, hoặc đường dẫn tệp sai trong CI không đọc được gì. Hãy chạy một lần với --verbose và kiểm tra nội dung yêu cầu mà CLI đã gửi. Nếu bạn thấy {{variables}} chưa được thay thế hoặc các giá trị trống, hãy sửa lỗi không khớp tên hoặc đường dẫn trước khi tin tưởng kết quả màu xanh lá cây.

Làm cách nào để giữ thông tin xác thực không nằm trong tệp dữ liệu của tôi? Giữ token và khóa hoàn toàn không nằm trong CSV hoặc JSON. Truyền chúng tại thời điểm chạy với --global-var hoặc --env-var từ kho bí mật CI của bạn, theo cách bạn truyền --global-var "api_key=$RUNTIME_API_KEY". Tệp dữ liệu chỉ nên chứa đầu vào kiểm thử và kết quả mong đợi, không chứa bất cứ thứ gì xác thực lần chạy.

Tôi có thể chạy cùng một dữ liệu đối với môi trường staging và production không? Có. Giữ kịch bản và tệp dữ liệu cố định và chuyển đổi mục tiêu bằng -e. Trỏ một kiểm tra yêu cầu kéo đến ID môi trường staging và một kiểm tra smoke test sau triển khai đến production bằng cách sử dụng cùng một kịch bản và cùng một dữ liệu, chỉ khác giá trị -e. Việc tách môi trường khỏi dữ liệu là lý do chính mà điều này hoạt động.

Tóm tắt

Cờ -d là toàn bộ câu chuyện về việc chạy theo dữ liệu cho Apidog CLI, và nó linh hoạt hơn vẻ ngoài ban đầu. Nó đọc một tệp CSV hoặc JSON cục bộ, hoặc một bộ dữ liệu được lưu trữ trong dự án của bạn bằng ID. Nó ghép nối với -n để lặp lại, với --env-var--global-var để cấu hình cho mỗi lần chạy, và với --on-error continue để một lần chạy hiển thị mọi hàng bị lỗi. Chạy nó từ một ID kịch bản trực tuyến hoặc từ một tệp đã xuất ngoại tuyến, và đọc kết quả từng lần lặp thông qua các trình báo cáo junitcli.

Xây dựng kịch bản một lần, mô tả mỗi trường hợp như một hàng, và để trình chạy mở rộng phạm vi bao phủ của bạn mỗi khi ai đó thêm một dòng vào tệp. Tải Apidog, trỏ apidog run vào tệp dữ liệu đầu tiên của bạn, và biến một kịch bản đơn lẻ thành một bảng các trường hợp chạy trên mỗi lần đẩy.

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