如何从JSON:API合规响应生成OpenAPI文档?含.json响应转.yaml格式最优实现方案
Hey there, these are solid questions—mapping JSON:API responses to OpenAPI docs is a common task, and doing it right ensures your API is well-documented and easy to consume. Let’s dive into both scenarios:
The key here is translating JSON:API’s structured conventions into OpenAPI’s schema and endpoint definitions. Here’s a practical approach:
First, map core JSON:API concepts to OpenAPI
JSON:API uses standardized structures likedata,attributes,relationships, andincluded—you’ll need to map these to reusable OpenAPI components:- The top-level
data(object or array) becomes the main response schema for your endpoint. attributestranslate directly to an object schema with your resource’s field definitions.relationshipsneed schemas that reference other resource identifiers or full resources (use$refto keep things DRY).includedis an array of related resources, so define it as an array usingoneOfto reference all possible included resource schemas.
- The top-level
Start manual for small APIs (builds understanding)
For a small API or single resource, writing the base OpenAPI spec manually helps you grasp the mapping. For example, apostsresource would look like this in YAML:components: schemas: PostResource: type: object properties: type: type: string example: "posts" id: type: string example: "1" attributes: $ref: '#/components/schemas/PostAttributes' relationships: $ref: '#/components/schemas/PostRelationships' PostAttributes: type: object properties: title: type: string example: "JSON:API Basics" body: type: string example: "Learn how to map JSON:API to OpenAPI..." PostRelationships: type: object properties: author: type: object properties: data: $ref: '#/components/schemas/AuthorResourceIdentifier'Then link this to your endpoint in the
pathssection:paths: /posts/{id}: get: responses: '200': description: A single post resource content: application/vnd.api+json: schema: $ref: '#/components/schemas/PostResource'Use automation for larger APIs
For bigger APIs, manual mapping gets tedious. Try these tools:json-schema-to-openapi-schema: Convert a JSON Schema (generated from your JSON:API response) into OpenAPI-compatible schemas.openapi-generator: Scrape your running JSON:API server to generate a base spec—configure it to recognize theapplication/vnd.api+jsonmedia type.- Postman: Import your JSON:API responses, then use Postman’s "Generate OpenAPI" feature to create a starting spec you can refine.
Let’s use the official JSON:API example response as a starting point:
{
"data": {
"type": "articles",
"id": "1",
"attributes": {
"title": "JSON:API paints my bikeshed!",
"body": "The shortest article. Ever.",
"createdAt": "2015-05-22T14:56:29.000Z",
"updatedAt": "2015-05-22T14:56:28.000Z"
},
"relationships": {
"author": {
"data": {"type": "people", "id": "9"}
},
"comments": {
"data": [
{"type": "comments", "id": "5"},
{"type": "comments", "id": "12"}
]
}
}
},
"included": [
{
"type": "people",
"id": "9",
"attributes": {
"firstName": "Dan",
"lastName": "Gebhardt",
"twitter": "dgeb"
}
},
{
"type": "comments",
"id": "5",
"attributes": {
"body": "First!"
}
},
{
"type": "comments",
"id": "12",
"attributes": {
"body": "I like XML better"
}
}
]
}
Follow these steps for the best results:
Step 1: Generate a JSON Schema from the response
Use a tool likejsonschema(Python CLI) or an online JSON Schema generator to create a raw schema from your JSON response. This gives you a foundation to work from.Step 2: Convert to OpenAPI-compatible schema
Usejson-schema-to-openapi-schema(npm package or online tool) to adjust the raw schema to fit OpenAPI’s rules—this fixes things like$schemareferences and aligns with OpenAPI’s component structure.Step 3: Refine into reusable JSON:API components
Automated tools create flat schemas, so split them into reusable parts (likeArticleResource,PersonResource) using$ref. For example:- Extract resource identifiers (like
PersonResourceIdentifier) for relationships. - Define
includedas an array ofoneOfyour resource schemas. - Add
constvalues fortypefields to enforce JSON:API’s type consistency.
- Extract resource identifiers (like
Step 4: Build the full OpenAPI YAML spec
Add theinfo,paths, andcomponentssections. Here’s a condensed version of the final spec:openapi: 3.0.3 info: title: JSON:API Example API version: 1.0.0 paths: /articles/{id}: get: summary: Retrieve a single article with related resources parameters: - name: id in: path required: true schema: type: string responses: '200': description: Article resource with included author and comments content: application/vnd.api+json: schema: type: object properties: data: $ref: '#/components/schemas/ArticleResource' included: type: array items: oneOf: - $ref: '#/components/schemas/PersonResource' - $ref: '#/components/schemas/CommentResource' components: schemas: ArticleResource: type: object properties: type: type: string const: "articles" id: type: string attributes: $ref: '#/components/schemas/ArticleAttributes' relationships: $ref: '#/components/schemas/ArticleRelationships' # ... (add other schemas like ArticleAttributes, PersonResource, etc.)Step 5: Validate and polish
Useswagger-cli validateor an online OpenAPI validator to check for errors. Fix issues like missing references, incorrect data formats (e.g.,date-timeforcreatedAt), and ensure all JSON:API conventions are reflected.
内容的提问来源于stack exchange,提问作者Pavel Shikhov

