Hai kỹ sư trong cùng một nhóm phát hành hai endpoint trong cùng một tuần. Một trả về created_at, cái còn lại trả về createdAt. Một phân trang bằng ?page=, cái kia bằng ?offset=. Riêng lẻ thì không có gì sai. Nhưng cùng nhau, chúng khiến API của bạn có cảm giác như được lắp ráp bởi những người lạ, và mọi client tiêu thụ nó đều phải chịu thiệt. Tệp OpenAPI được xác thực ổn. Nó phân tích cú pháp, hiển thị trong Swagger UI, tạo SDK. Nó chỉ không nhất quán, và một trình xác thực thông thường không có gì để nói về điều đó.
Đó chính là khoảng trống mà một linter lấp đầy. Một trình xác thực trả lời “liệu đặc tả này có phải là OpenAPI hợp lệ không?” Một linter trả lời “liệu đặc tả này có tuân thủ các quy tắc chúng ta đã thống nhất không?” Công cụ mã nguồn mở phổ biến nhất cho câu hỏi thứ hai là Spectral, linter của Stoplight dành cho các tài liệu JSON và YAML. Nó đi kèm với một bộ quy tắc OpenAPI tích hợp, cho phép bạn viết các quy tắc của riêng mình và chạy từ terminal hoặc trình chỉnh sửa của bạn. Nếu bạn muốn một cách miễn phí, có thể viết script để thực thi hướng dẫn về phong cách API, Spectral là điểm dừng đầu tiên hiển nhiên, và hướng dẫn này sẽ chỉ cho bạn cách sử dụng nó đúng cách.
Nó cũng cho bạn thấy sự đánh đổi. Spectral là một bộ quy tắc bạn tự xây dựng và duy trì. Đối với các nhóm muốn có các kiểm tra tính nhất quán, máy chủ giả lập và các bài kiểm tra có thể chạy được từ một nơi mà không cần tự viết các quy tắc YAML, Apidog tích hợp công việc đó vào chính bề mặt thiết kế. Chúng ta sẽ ghi nhận đầy đủ Spectral trước, sau đó sẽ chỉ ra con đường "tất cả trong một" giúp bạn tiết kiệm chi phí bảo trì.
Spectral thực sự làm gì
Spectral là một linter chung. Bạn chỉ nó vào một tài liệu có cấu trúc, cung cấp cho nó một bộ quy tắc, và nó sẽ báo cáo mọi nơi tài liệu vi phạm quy tắc, với số dòng và mức độ nghiêm trọng. Nó không dành riêng cho OpenAPI; nó hiểu OpenAPI, AsyncAPI và Arazzo ngay từ đầu, và bạn có thể lint bất kỳ tệp JSON hoặc YAML nào bằng các quy tắc tùy chỉnh.

Lý do nó quan trọng đối với công việc API là bộ quy tắc spectral:oas tích hợp sẵn. Bộ quy tắc đó mã hóa một danh sách dài các quy ước OpenAPI: các hoạt động nên có operationId, đối tượng info nên chứa mô tả và thông tin liên hệ, các thẻ nên được định nghĩa trước khi sử dụng, các tham số không nên trùng lặp. Chạy nó với một đặc tả thực tế và bạn gần như luôn nhận được một danh sách cảnh báo ngay lần thử đầu tiên. Không cái nào trong số đó làm hỏng trình phân tích cú pháp. Tất cả đều khiến đặc tả khó sử dụng hơn.
Đây là một công việc khác với xác thực cấu trúc. Một công cụ như swagger-cli hoặc Redocly trả lời liệu tài liệu có tuân thủ lược đồ OpenAPI hay không. Spectral trả lời liệu tài liệu có tuân thủ phong cách nội bộ của bạn trên hết. Bạn muốn cả hai, và hai kiểm tra này kết hợp gọn gàng trong một pipeline. Chúng tôi sẽ đi sâu vào phần xác thực trong hướng dẫn về cách xác thực các đặc tả OpenAPI; bài viết này nói về phần phong cách và tính nhất quán.
Cài đặt Spectral và chạy lần lint đầu tiên của bạn
Spectral được phát hành dưới dạng gói npm. CLI là @stoplight/spectral-cli. Cài đặt nó trên toàn cầu:
npm install -g @stoplight/spectral-cli
Node.js là sự phụ thuộc hệ thống duy nhất, vì vậy bất kỳ máy nào hoặc hình ảnh CI nào đã cài đặt Node đều có thể chạy nó. Nếu bạn không muốn cài đặt nó trên toàn cầu, npx @stoplight/spectral-cli ... hoạt động tốt trên các build runner tạm thời.
Spectral cần một bộ quy tắc để biết phải kiểm tra gì. Quy ước là một tệp có tên .spectral.yaml trong thư mục làm việc của bạn. Tệp nhỏ nhất hữu ích sẽ mở rộng các quy tắc OpenAPI tích hợp:
# .spectral.yaml
extends: ["spectral:oas"]
Bây giờ hãy lint một đặc tả. Với tệp .spectral.yaml trong thư mục hiện tại, Spectral sẽ tự động nhận diện nó:
spectral lint openapi.yaml
Hoặc chỉ định một bộ quy tắc một cách rõ ràng:
spectral lint openapi.yaml --ruleset .spectral.yaml
Đầu ra được thiết kế để dễ đọc. Mỗi phát hiện hiển thị dòng và cột, mức độ nghiêm trọng, quy tắc đã được kích hoạt và một thông báo dễ hiểu:
openapi.yaml
3:6 warning info-contact Info object should contain `contact` object.
5:10 error info-description OpenAPI object info `description` must be present.
✖ 2 problems (1 error, 1 warning, 0 infos, 0 hints)
Lần chạy đầu tiên đó đối với một đặc tả hiện có là lúc hầu hết các nhóm nhận ra sự lệch lạc đã xâm nhập nhiều đến mức nào. Các quy tắc chưa bao giờ được thực thi, vì vậy không ai tuân theo chúng.
Viết các quy tắc của riêng bạn
Bộ quy tắc tích hợp là một điểm khởi đầu, không phải đích đến. Giá trị thực sự của Spectral là mã hóa các quy ước của nhóm bạn thành các quy tắc mà máy sẽ kiểm tra mỗi khi có thay đổi. Một quy tắc có bốn phần chuyển động: cái gì để xem xét (given, một biểu thức JSONPath), cái gì để kiểm tra (then, một hàm), mức độ nghiêm trọng (severity), và thông báo khi nó thất bại (message).
Đây là một quy tắc thực thi đường dẫn kebab-case, một quy ước nội bộ phổ biến:
# .spectral.yaml
extends: ["spectral:oas"]
rules:
paths-kebab-case:
description: Paths should be kebab-case.
message: "{{property}} should be kebab-case (lower-case, hyphen-separated)"
severity: warn
given: $.paths[*]~
then:
function: pattern
functionOptions:
match: "^(\\/|[a-z0-9-.]+|{[a-zA-Z0-9_]+})+$"
given chọn mọi khóa đường dẫn. then chạy hàm pattern tích hợp với một biểu thức chính quy. Bất cứ điều gì không khớp với mẫu đều được báo cáo dưới dạng cảnh báo với thông báo của bạn. Bạn có thể cấm ID số nguyên thay vì UUID, yêu cầu phản hồi lỗi trên mỗi POST, cấm số phiên bản trong URL máy chủ, hoặc yêu cầu mọi hoạt động phải có mô tả. Spectral cung cấp một số hàm cốt lõi (truthy, pattern, schema, length, enumeration, và nhiều hơn nữa) nên hầu hết các quy ước không cần bất kỳ đoạn mã nào.
Khi một quy tắc cần logic mà một tùy chọn hàm không thể diễn tả, Spectral cho phép bạn viết quy tắc bằng JavaScript hoặc TypeScript và nhập các hàm tùy chỉnh. Đó là lúc công cụ trở nên mạnh mẽ và cũng là lúc công việc bảo trì bắt đầu. Nếu bạn muốn tìm hiểu sâu đến mức đó, chúng tôi có một hướng dẫn đầy đủ về cách xây dựng các quy tắc Spectral tùy chỉnh bằng TypeScript.
Mức độ nghiêm trọng, và làm cho bản build thất bại
Mỗi quy tắc Spectral đều có một mức độ nghiêm trọng: error, warn, info, hoặc hint. Theo mặc định, CLI chỉ thoát với mã khác 0 khi nó tìm thấy một error. Các cảnh báo vẫn được in ra nhưng không làm cho quá trình chạy thất bại. Điều này là tốt khi bạn đang dọn dẹp một đặc tả cũ và không muốn hàng ngàn cảnh báo chặn mọi lần hợp nhất.
Khi đặc tả của bạn đã sạch, hãy siết chặt cổng. Cờ --fail-severity kiểm soát ngưỡng:
spectral lint openapi.yaml --fail-severity=warn
Bây giờ một cảnh báo cũng trả về mã thoát 1, đây là điều mà một bước CI đọc để đánh dấu nó là thất bại. Đây là cơ chế biến một linter thành một cổng chất lượng thực sự: pipeline sẽ chặn hợp nhất ngay khi đặc tả lệch khỏi hướng dẫn phong cách. Bạn cũng có thể ghi đè mức độ nghiêm trọng của từng quy tắc trong bộ quy tắc của mình, nâng một quy tắc bạn quan tâm từ warn lên error hoặc tắt một quy tắc không phù hợp với nhóm của bạn bằng cách đặt nó thành off.
Chạy Spectral trong CI
Một linter chỉ chạy khi ai đó nhớ thì không phải là một cổng. Mục đích là để chạy nó trên mọi lần đẩy, trên một máy sạch, với cùng một bộ quy tắc cho tất cả mọi người. Spectral làm điều này một cách ngắn gọn. Đây là một công việc GitHub Actions sẽ lint đặc tả trên bất kỳ pull request nào chạm đến nó:
name: Lint OpenAPI
on:
pull_request:
paths:
- "openapi.yaml"
jobs:
spectral:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npm install -g @stoplight/spectral-cli
- run: spectral lint openapi.yaml --fail-severity=warn
Để báo cáo phong phú hơn, Spectral có thể xuất JUnit XML, mà hầu hết các bảng điều khiển CI đều phân tích thành một cây pass/fail:
spectral lint openapi.yaml -f junit -o results.xml
Kết nối artifact đó vào bảng điều khiển của bạn và mọi cộng tác viên sẽ thấy quy tắc nào đã thất bại và ở đâu, mà không cần đọc nhật ký thô. Nếu bạn muốn có cái nhìn rộng hơn về việc kết hợp các kiểm tra cấu trúc, linting và phát hiện thay đổi gây lỗi, các mẫu OpenAPI-in-CI sẽ tổng quát hơn bất kỳ công cụ đơn lẻ nào. Coi đặc tả như code là tư duy giúp tất cả những điều này gắn kết.
Nơi Spectral đòi hỏi nhiều ở bạn
Spectral làm tốt công việc của nó. Vấn đề thực sự là nó chỉ làm một việc, và phần còn lại của vòng đời đặc tả là vấn đề của bạn để kết nối lại với nhau. Một vài thực tế xuất hiện khi một nhóm áp dụng nó vượt ra ngoài bản demo.
Bạn sở hữu bộ quy tắc. Các quy tắc spectral:oas tích hợp sẵn là chung chung. Hướng dẫn phong cách thực sự của bạn nằm trong các quy tắc tùy chỉnh mà bạn viết, xem xét, tạo phiên bản và duy trì cập nhật khi các quy ước phát triển. Bộ quy tắc đó trở thành một codebase nhỏ với gánh nặng bảo trì riêng, và JSONPath cùng với các hàm tùy chỉnh là một kỹ năng không phải ai trong nhóm cũng có.
Nó lint tài liệu, không phải API. Spectral đọc tệp. Nó không thể cho bạn biết liệu dịch vụ đang chạy có thực sự trả về những gì đặc tả hứa hẹn hay không. Một đặc tả có thể vượt qua mọi quy tắc lint nhưng vẫn mô tả một endpoint mà việc triển khai đã khác biệt từ nhiều tháng trước. Để lấp đầy khoảng trống đó có nghĩa là gửi các yêu cầu thực tế và xác nhận các phản hồi, đây hoàn toàn là một công cụ khác.
Nó là một mảnh ghép trong một chuỗi dài hơn. Sau khi linting, bạn vẫn cần các mock cho các nhóm frontend, một trang web tài liệu và một bộ kiểm thử tự động. Mỗi cái là một công cụ riêng biệt để cài đặt, cấu hình và giữ đồng bộ với đặc tả. Linter không biết về bất kỳ công cụ nào trong số đó, vì vậy đặc tả sẽ được phân tích cú pháp và diễn giải lại ở mỗi giai đoạn.
Không có điều nào trong số này là lời chỉ trích Spectral. Nó là một linter tập trung và nó trung thực về phạm vi của mình. Nhưng "tập trung" có nghĩa là công việc tích hợp sẽ rơi vào bạn.
Cách dễ hơn: tính nhất quán được tích hợp vào bề mặt thiết kế
Đây là con đường khác. Thay vì coi tính nhất quán là một bước linting được thêm vào sau khi đặc tả được viết, Apidog coi đó là một phần của quá trình viết đặc tả.
Apidog là một nền tảng API tất cả trong một: bạn thiết kế lược đồ, gỡ lỗi yêu cầu, xây dựng các kịch bản kiểm thử, giả lập endpoint và xuất bản tài liệu trong một không gian làm việc duy nhất. Bởi vì việc thiết kế diễn ra bên trong công cụ, các kiểm tra tính nhất quán xảy ra ngay khi bạn nhập. Trình thiết kế trực quan sẽ hiển thị các vấn đề cấu trúc ngay khi chúng xuất hiện, giống như cách một trình biên dịch gạch chân lỗi cú pháp, vì vậy bạn khắc phục chúng trước khi chúng được commit. Bạn không chạy một linter riêng biệt sau đó; trình chỉnh sửa chính là linter.
Sự khác biệt lớn hơn nằm ở mọi thứ phía sau. Hợp đồng mà bạn thiết kế sẽ trở thành máy chủ giả lập, tài liệu tương tác và các kịch bản kiểm thử của bạn, không cần phân tích cú pháp lại và không cần công cụ thứ hai để giữ đồng bộ. Khi bạn muốn các kiểm tra đó trong một pipeline, Apidog CLI chạy các kịch bản kiểm thử của bạn mà không cần giao diện người dùng từ terminal và thoát với mã khác 0 khi thất bại, chính xác là hành vi cổng bạn mong muốn từ một linter, ngoại trừ việc nó kiểm tra API đang chạy so với hợp đồng thay vì chỉ đọc tệp. Cài đặt nó bằng một lệnh npm và trỏ nó vào một kịch bản:
npm install -g apidog-cli
apidog run --access-token $APIDOG_ACCESS_TOKEN -t <scenarioId> -e <environmentId> -r cli
Điều đó lấp đầy khoảng trống mà Spectral bỏ ngỏ. Spectral xác nhận tài liệu tuân thủ phong cách của bạn. Apidog CLI xác nhận việc triển khai vẫn khớp với tài liệu. Để tham khảo đầy đủ các cờ, hãy chạy apidog run --help hoặc đọc hướng dẫn CLI đầy đủ.
Vì vậy, sự đánh đổi là có thật và đáng được nêu rõ ràng. Spectral cung cấp cho bạn một linter miễn phí, có thể viết script, không phụ thuộc vào nhà cung cấp mà bạn tự lắp ráp và duy trì. Apidog cung cấp cho bạn tính nhất quán, mocking, tài liệu và các bài kiểm thử có thể chạy được từ một nguồn sự thật duy nhất, với ít công việc kết nối hơn nhiều. Nếu một bước linting di động trong chuỗi công cụ hiện có là tất cả những gì bạn cần, Spectral là một câu trả lời tốt. Nếu bạn muốn toàn bộ vòng đời được duy trì mà không trở thành một dự án công cụ riêng, con đường tích hợp sẽ tốn ít chi phí hơn theo thời gian.
Spectral vs Apidog: So sánh nhanh
| Khả năng | Spectral | Apidog |
|---|---|---|
| Linting phong cách OpenAPI | Có, qua spectral:oas + quy tắc tùy chỉnh |
Có, hiển thị trực tiếp trong trình thiết kế |
| Quy tắc tùy chỉnh | Có, YAML hoặc JS/TS, bạn tự duy trì | Các quy ước được thực thi bởi trình chỉnh sửa, không cần code quy tắc |
| Xác thực cấu trúc | Cùng với Redocly hoặc một trình xác thực khác | Tích hợp sẵn trong thời gian thiết kế |
| Máy chủ giả lập | Không | Có |
| Tài liệu tự động tạo | Không | Có |
| Kiểm thử API có thể chạy | Không | Có, qua Apidog CLI |
| Cổng CI | spectral lint --fail-severity=warn |
apidog run thoát mã khác 0 |
| Chi phí | Miễn phí, mã nguồn mở | Gói miễn phí, gói trả phí |
Sử dụng bảng này như một công cụ hỗ trợ ra quyết định, không phải bảng điểm. Lựa chọn đúng đắn là lựa chọn phù hợp với mức độ bạn muốn một công cụ sở hữu trong vòng đời.
Các câu hỏi thường gặp
Spectral có miễn phí không? Có. Spectral là mã nguồn mở theo giấy phép Apache 2.0, được duy trì bởi Stoplight. CLI, bộ quy tắc OpenAPI tích hợp và việc tạo quy tắc tùy chỉnh đều miễn phí sử dụng.
Spectral có xác thực rằng đặc tả của tôi là OpenAPI hợp lệ không? Một phần. Các quy tắc tích hợp bắt được nhiều vấn đề cấu trúc, nhưng Spectral là một linter, không phải một trình xác thực lược đồ chuyên dụng. Hãy kết hợp nó với một trình xác thực để có độ phủ cấu trúc đầy đủ. Hướng dẫn về xác thực đặc tả OpenAPI bao gồm khía cạnh đó, và các công cụ xác thực OpenAPI tốt nhất so sánh các lựa chọn.
Spectral có thể kiểm tra API đang chạy của tôi không? Không. Spectral chỉ đọc tệp đặc tả. Để kiểm tra xem API trực tiếp có khớp với hợp đồng hay không, bạn cần một trình chạy gửi các yêu cầu thực tế và xác nhận các phản hồi, chẳng hạn như Apidog CLI.
Làm thế nào để tôi khiến một cảnh báo của Spectral làm thất bại bản build CI của tôi? Chạy spectral lint openapi.yaml --fail-severity=warn. Theo mặc định, chỉ mức độ nghiêm trọng error làm thất bại bản build; --fail-severity=warn cũng khiến các cảnh báo trả về mã thoát khác 0.
Sự khác biệt giữa Spectral và Apidog là gì? Spectral là một linter mã nguồn mở tập trung mà bạn cấu hình và duy trì. Apidog là một nền tảng tất cả trong một nơi thiết kế, kiểm tra tính nhất quán, mocking, tài liệu và kiểm thử cùng tồn tại, vì vậy bạn ít phải lắp ráp và ít phải đồng bộ hóa hơn. Xem Apidog vs Swagger để so sánh liên quan về bối cảnh công cụ thiết kế.
Tóm tắt
Spectral giải quyết một vấn đề thực sự mà các trình xác thực đơn giản bỏ qua: giữ cho đặc tả OpenAPI nhất quán với các quy ước mà nhóm của bạn đã thống nhất. Cài đặt @stoplight/spectral-cli, mở rộng spectral:oas, thêm một vài quy tắc tùy chỉnh và bảo vệ pipeline của bạn bằng --fail-severity=warn. Đối với nhiều nhóm, điều đó là đủ, và không tốn kém gì.
Chi phí sẽ xuất hiện sau đó, trong các quy tắc bạn duy trì và phần còn lại của vòng đời bạn kết nối xung quanh linter. Nếu bạn muốn có tính nhất quán, mock, tài liệu và các bài kiểm thử có thể chạy được từ một nguồn sự thật duy nhất, hãy tải xuống Apidog và xây dựng đặc tả của bạn nơi các kiểm tra đã là một phần của bề mặt. Dù bằng cách nào, mục tiêu đều giống nhau: một đặc tả mà toàn bộ nhóm của bạn có thể tin tưởng, được thực thi bởi một cỗ máy thay vì một hy vọng.
