Document your endpoints with OpenAPI
KrakenD Enterprise generates the OpenAPI documentation (formerly Swagger) of your API when you run the krakend openapi export command (see Exporting to OpenAPI). The documentation/openapi configuration enriches that export with your company information, reusable components, and a detailed description of every endpoint, so API consumers get complete documentation without you maintaining a separate specification.
OpenAPI configuration
The OpenAPI documentation configuration has two different placements that you can use:
servicelevel: Defines the general business information and metadata that gives context about your company and how API consumers can get in touch with you. It is common to all endpoints.endpointlevel: Defines the documentation and metadata for a specific endpoint.
Both configuration placements are optional, and when you don’t provide the information, KrakenD sets defaults.
Setting the basic API information
At the service level (the root of the configuration file), declare the documentation/openapi namespace inside extra_config to set the general API information for your developers. All the fields are optional.
The following example shows the available fields:
{
"version": 4,
"name": "Your KrakenD API",
"extra_config": {
"documentation/openapi": {
"description": "This is a sample server. You can find out more at [example.com](https://example.com)",
"version": "1.0.0",
"host": "api.example.com",
"base_path": "/v1",
"terms_of_service": "https://example.com/terms",
"contact_name": "API Support",
"contact_email": "[email protected]",
"contact_url": "https://example.com/developers",
"license_name": "MIT",
"license_url": "https://opensource.org/licenses/MIT",
"tag_definition": [
{
"name": "Admin",
"description": "All endpoints for administrative users"
}
],
"components_schemas": {
"Pet": {
"type": "object",
"required": ["id","name"],
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
},
"tag": {
"type": "string"
}
}
},
"Pets": {
"type": "array",
"maxItems": 100,
"items": {
"$ref": "#/components/schemas/Pet"
}
}
},
"components_parameters": {
"PageParam": {
"name": "page",
"in": "query",
"description": "The page number to retrieve",
"required": false,
"schema": {
"type": "integer"
}
}
}
}
}
}
Fields of Generate documentation using OpenAPI
base_pathstring- A starting path that prefixes every endpoint.Example:
"/v1" components_parametersobject- Reusable OpenAPI parameter objects that the generated spec declares under
components/parameters. You can pass either the parameter object or a base64 string.Example:{"MyParam":{"in":"query","name":"my_param","schema":{"type":"string"}}}Properties of
components_parameterscan use a name matching the pattern.*, and their content is an[string object] components_schemasobject- The JSON Schemas you can reuse inside endpoint definitions using
ref. You can pass either the JSON Schema object or a base64 string.Example:{"Pet":{"required":["id","name"],"type":"object"}}Properties of
components_schemascan use a name matching the pattern.*, and their content is an[string object] contact_emailstring- The email address where consumers of your API can reach you.Example:
"[email protected]" contact_namestring- The name of the person or team responsible for the API.Example:
"API Support" contact_urlstring- The URL where consumers of your API find contact information.Example:
"https://example.com/developers" cookie_namestring- The name of the cookie declared under
components/securitySchemesin the generated OpenAPI spec.Defaults to"SESSIONID" custom_security_schemesobject- Adds custom security schemes under
components/securitySchemesin the generated OpenAPI spec. Use it to define security schemes different from the built-in ones (e.g.,jwt,apikey,cookie). Declare each scheme with its full definition (e.g.,"OAuth2Security":{...}), and enable it in each endpoint by writing its name with an empty object (e.g.,{"OAuth2Security":{}}).Example:{"OAuth2Security":{"description":"OAuth2 security scheme","flows":{"authorizationCode":{"authorizationUrl":"https://example.com/oauth/authorize","scopes":{},"tokenUrl":"https://example.com/oauth/token"}},"type":"oauth2"}}Properties of
custom_security_schemescan use a name matching the pattern^.*$, and their content is anobjectwith the following properties: descriptionstring- An introductory, optionally verbose, explanation of your API supporting CommonMark syntax. To load an external markdown file, use flexible configuration, for instance
"description": {{include "openapi/intro.md" | toJson }}Example:"Hi there, I am [OpenAPI](https://www.krakend.io/docs/enterprise/endpoints/openapi/)" hoststring- The hostname where you will publish your API.Example:
"api.example.com" jwt_keystring- The name of the JWT key declared under
components/securitySchemesin the generated OpenAPI spec.Defaults to"KrakenD-JWT" license_namestring- The name of the license of your API, e.g.,
Apache 2.0.Example:"MIT" license_urlstring- The URL where the license is hosted.Example:
"https://opensource.org/licenses/MIT" serversarray of objects- The list of servers where the API is hosted. The server URL can be a relative path, e.g.,
/v1, or an absolute URL. The URL might contain{variables}, although only OpenAPI recognizes them: KrakenD treats them as literal strings.Examples:[{"url":"/v1"}],[{"url":"https://example.com:{port}","variables":{"port":{"default":"8443","enum":["8443","443"]}}}]Each item of servers accepts the following properties:descriptionstring- A short description of the server URL.
url* string, object- The URL of the server, used as the base path for all endpoints.
variablesobject- A Server Variable Object according to the OpenAPI specification. The variable name is the key and the value is the default value for that variable.
Properties of
variablescan use a name matching the pattern^.*$, and their content is an[string object]
tag_definitionarray of objects- Sets a detailed description for the tags classifying endpoints when generating the OpenAPI spec.Example:
[{"description":"Description of tag1","name":"Tag1"}]Each item of tag_definition accepts the following properties:descriptionstring- Describes what this tag groups.
name* string- The name of the tag. You will use this name in each endpoint.
terms_of_servicestring- The URL to the terms of service for using this API.Example:
"https://example.com/terms" versionstring- The version of your API, e.g.,
1.0.Example:"1.0"
The name specified in the root of the configuration (outside the OpenAPI’s extra_config) is used as the title of your API. If none is present, the string KrakenD - API Gateway is the default.
Use components_parameters to declare reusable parameter objects that the generated specification includes under components/parameters. Like components_schemas, each parameter can be a full OpenAPI parameter object or a base64-encoded string. To reuse a parameter in an endpoint, add an item with its ref to the query_definition, param_definition, or header_definition list, e.g., {"ref": "PageParam"}. Write only the parameter name, without the #/components/parameters/ prefix.
To include a full markdown file in the introduction, use flexible configuration. For instance, if you write a markdown file under partials/openapi/intro.md, you can load it as follows:
{
"version": 4,
"name": "Your KrakenD API",
"extra_config": {
"documentation/openapi": {
"description": {{include "openapi/intro.md" | toJson }}
}
}
}
Documenting endpoints
In addition to setting global metadata for the whole API, you can add information to each endpoint so consumers understand what every endpoint does. All fields are optional:
Fields of Generate endpoint documentation using OpenAPI
audiencearray of strings- The list of audiences that will consume this endpoint. These values do not define the gateway logic in any way. They are a way to group endpoints and filter them out when generating the OpenAPI documentation. Use
*to indicate an endpoint will be present in any audience generated.Example:["gold","silver","*"] custom_security_schemesobject- The custom security schemes that apply to this endpoint. Write each scheme name as declared in the service-level
custom_security_schemes, with an empty object as value, e.g.,{"OAuth2Security":{}}.Example:{"OAuth2Security":{}}Properties of
custom_security_schemescan use a name matching the pattern^.*$, and their content is anobjectwith the following properties: descriptionstring- A detailed explanation of what the endpoint does, supporting CommonMark syntax. Use
summaryfor a short version.Example:"Lists all users in the system, paginated in blocks of 50 users" disable_default_response_definitionsboolean- By default, KrakenD adds a
500and a200response definition to the endpoint. Set this property totrueto avoid this behavior.Defaults tofalse exampleobject, string- Deprecated in OAS3 (use
response_definitioninstead). A free form JSON object or a string you would like to show as a sample response of the endpoint. The examples assume they are JSON content types except when using theoutput_encoding=string. header_definitionarray of objects- Sets a detailed description for the headers allowed in the endpoint. Make sure to include the same headers in the endpoint’s
input_headers.Example:[{"description":"The type of content","name":"Content-Type"}]Each item of header_definition accepts the following properties:descriptionstring- The description of the header.Example:
"The Content-Type sets the encoding of the request" enumarray of [array boolean integer number object string]s- The allowed values for this headerExample:
["application/json","application/xml"] hideboolean- Hides this header from the generated documentation.Defaults to
false namestring- The name of the header, as declared in
input_headers refstring- The name of a parameter declared in the service-level
components_parameters, without the#/components/parameters/prefix. When you setref, thenameis not needed.Example:"PageParam" requiredboolean- Set to
truewhen this header is required.Defaults tofalse type- The type of data according to the OpenAPI specPossible values are:
"integer","string","boolean","object","array","float","date-time"Example:"string"Defaults to"string"
operation_idstring- A unique identifier of the operation, usually the method plus the endpoint. If provided, each ID must be unique among all operations described in your API.Example:
"GET/foo" param_definitionarray of objects- Sets a detailed description for the URL parameters (e.g.,
/foo/{param}) required in the endpoint. Write each parameter name exactly as in the endpoint definition.Example:[{"description":"The unique user ID","name":"id_user"}]Each item of param_definition accepts the following properties:descriptionstring- The description of the parameter.
enumarray of [array boolean integer number object string]s- The allowed values for this parameterExample:
["application/json","application/xml"] examplestring, number, boolean, array, object- An example value for this parameter. This example is injected in the spec as is.
examplesobject- Multiple example values for this parameter, where each key is the name of the example.
Properties of
examplescan use a name matching the pattern^.*$, and their content is an[string number boolean array object] format- The extending format for the previously defined type. If the type is
numberorstring, you can apply one of the available formats. The linter does not check that the format matches the type.Possible values are:"int32","int64","float","double","date","date-time","byte","uuid","" hideboolean- Hides this parameter from the generated documentation, although it is still part of the endpoint definition.Defaults to
false namestring- The name of the parameter, as declared in
endpointwithout the curly braces{} refstring- The name of a parameter declared in the service-level
components_parameters, without the#/components/parameters/prefix. When you setref, thenameis not needed.Example:"PageParam" requiredboolean- A path parameter is always mandatory on KrakenD, but you can still generate the OpenAPI documentation saying otherwise.Defaults to
true type- The type of data according to the OpenAPI specPossible values are:
"integer","number","string","boolean","object","array","float","date-time"Example:"string"Defaults to"string"
query_definitionarray of objects- Sets a detailed description for the query strings allowed in the endpoint. Make sure to include the same strings in the endpoint’s
input_query_strings.Example:[{"description":"The number of the page","name":"page"}]Each item of query_definition accepts the following properties:descriptionstring- The description of the query string.
enumarray of [array boolean integer number object string]s- The allowed values for this query definition
examplestring, object, array, boolean, integer, null, number- An example value for this query string.
format- The extending format for the previously defined type. If the type is
numberorstring, you can apply one of the available formats. The linter does not check that the format matches the type.Possible values are:"int32","int64","float","double","date","date-time","byte","uuid","" hideboolean- Hides this query string from the generated documentation.Defaults to
false namestring- The name of the query string, as declared in
input_query_strings. refstring- The name of a parameter declared in the service-level
components_parameters, without the#/components/parameters/prefix. When you setref, thenameis not needed.Example:"PageParam" requiredboolean- Set to
truewhen this query string is required.Defaults totrue type- The type of data according to the OpenAPI specPossible values are:
"integer","number","string","boolean","object","array","float","date-time"Defaults to"string"
request_definitionarray- Describes the payload needed to consume the endpoint. If a JSON Schema validation exists, it takes precedence when generating the documentation. An example use case is when you need to document a
multipart/form-datarequest body. This property is an array because you can document requests with multiple content types.Example:[{"content_type":"application/json","description":"Updates the user","example":{"first_name":"Mary","id_user":33}}]Each item of request_definition accepts the following properties:content_type* string- The content type of the request payload, e.g.,
application/json. You cannot repeat this content type in another item. descriptionstring- The description of the payload this endpoint accepts.
examplestring, object, array, boolean, integer, null, number- A free form JSON object or a string you would like to show as a sample request payload of the endpoint. The examples assume they are JSON content types.
example_schemastring, object- A JSON schema that describes the request format for the accepted payload in the endpoint. Use either
exampleorexample_schema, but not both. examplesobject- A free form JSON object or a string you would like to show as a sample request payload of the endpoint. The examples assume they are JSON content types.Examples:
{"Example 1":{"msg":"a message"}},{"Example 1":{"msg":"a message"},"Example 2":{"error":"an error message"}} refstring- The relative reference to the
components/schemasOpenAPI definition that describes the accepted request. Notice that the path#/components/schemas/is not needed.Example:"your_schema_name"
response_definitionobject- Describes the different status codes returned by this endpoint. Each key is a status code represented as a string, e.g.,
200(success),500(internal error), ordefault.Example:{"404":{"@comment":"Some comment","content_type":"application/json","description":"Page not found","example":{"status":"KO"}}}Properties of
response_definitioncan use a name matching the patterndefault|^[0-9]+$, and their content is an serversarray of objects- The list of servers where this endpoint is hosted, when they differ from the service-level
servers. The server URL can be a relative path, e.g.,/v1, or an absolute URL. The URL might contain{variables}, although only OpenAPI recognizes them: KrakenD treats them as literal strings.Examples:[{"url":"/v1"}],[{"url":"https://example.com:{port}","variables":{"port":{"default":"8443","enum":["8443","443"]}}}]Each item of servers accepts the following properties:descriptionstring- A short description of the server URL.
url* string, object- The URL of the server, used as the base path for this endpoint.
variablesobject- A Server Variable Object according to the OpenAPI specification. The variable name is the key and the value is the default value for that variable.
Properties of
variablescan use a name matching the pattern^.*$, and their content is an[string object]
summarystring- A short summary for the endpoint. Use
descriptionfor a longer explanation. tagsarray of strings- You can assign a list of tags to each API operation. If you declare tags in the
tag_definitionat the OpenAPI service level, they will have a description in the documentation. Tagged operations may be handled differently by tools and libraries. For example, Swagger UI uses tags to group the displayed operations.
The example below sets a rich OpenAPI documentation for two endpoints. Notice that:
- The
GET /usersendpoint describes the?pagequery string and provides a full example response underresponse_definition. - The
PUT /users/{id_user}endpoint also adds arequest_definitionthat defines the payload consumers need to send.
Have a look at the different parameters:
{
"version": 4,
"$schema": "https://www.krakend.io/schema/krakend.json",
"host": [
"http://localhost:8080"
],
"debug_endpoint": true,
"echo_endpoint": true,
"endpoints": [
{
"endpoint": "/users",
"method": "GET",
"extra_config": {
"documentation/openapi": {
"description": "Lists all users in the system, paginated in blocks of 50 users",
"summary": "List all users",
"operation_id": "GET/users",
"tags": [
"users"
],
"audience": [
"internal"
],
"query_definition": [
{
"name": "page",
"required": false,
"description": "Pass a ?page= if you want to use the pagination"
}
],
"response_definition": {
"200": {
"content_type": "application/json",
"example": {
"users": [
{
"id": 1,
"first_name": "Juliana",
"last_name": "Claire",
"email": "[email protected]"
},
{
"id": 2,
"first_name": "Jeannette",
"last_name": "Hugonneau",
"email": "[email protected]"
}
]
}
}
}
}
},
"backend": [
{
"url_pattern": "/api/1.0/users/list"
}
]
},
{
"endpoint": "/users/{id_user}",
"method": "PUT",
"extra_config": {
"documentation/openapi": {
"description": "The PUT method updates the data for the given id_user. You only need to pass the fields you want to update.",
"summary": "Updates the user data",
"operation_id": "PUT/users/id_user",
"tags": [
"users"
],
"audience": [
"internal"
],
"request_definition": [
{
"content_type": "application/json",
"description": "Updates provided fields. All fields are optional, id_user taken from the URL",
"example": {
"address": "Suite 543 907 Green Forks, Wavamouth, CT 10807-8479",
"first_name": "Felix",
"last_name": "Richardson"
}
}
],
"response_definition": {
"200": {
"content_type": "application/json",
"example": {
"id_user": 33007,
"status": "success"
}
}
}
}
},
"backend": [
{
"url_pattern": "/api/1.0/users/update/{id_user}"
}
]
}
]
}
The example above is verbose for only two endpoints, and it does not even use all the available options. You can move any part of the configuration to an external file using Flexible Configuration. You can generate the OpenAPI file without any of this, but consumers appreciate a rich and detailed documentation. The following example moves the documentation out of the endpoint definition, although there are more ways of doing it:
{
"endpoints": [
{
"endpoint": "/users",
"method": "GET",
"extra_config": {
"documentation/openapi": {
"$ref": "./documentation/GET_users.json"
}
},
"backend": [
{
"url_pattern": "/api/1.0/users/list"
}
]
},
{
"endpoint": "/users/{id_user}",
"method": "PUT",
"extra_config": {
"documentation/openapi": {
"$ref": "./documentation/PUT_users_id_user.json"
}
},
"backend": [
{
"url_pattern": "/api/1.0/users/update/{id_user}"
}
]
}
]
}
Integration with JSON Schema
When your endpoint uses a validation/json-schema, the documentation of all write methods (POST, PUT, PATCH, DELETE) includes its validation conditions automatically.
You don’t need to add anything else to the configuration, but you can still explain the payloads using the request_definition property.
Define different audiences of your OpenAPI
When you declare your endpoints, you might want to keep some of them out of the final documentation export because the audience consuming them doesn’t need to know they exist.
For instance, your API exposes endpoints like /user, /cart, or /admin, where the administration endpoint is for internal usage. Your end users are not supposed to use it, so it should not appear in their documentation.
For cases like this, add audience definitions to the endpoints. For instance:
[
{
"endpoint": "/user",
"extra_config": {
"documentation/openapi": {
"description": "The user endpoint",
"audience": [
"public",
"internal"
]
}
}
},
{
"endpoint": "/cart",
"extra_config": {
"documentation/openapi": {
"description": "The cart endpoint",
"audience": [
"public",
"internal"
]
}
}
},
{
"endpoint": "/admin",
"extra_config": {
"documentation/openapi": {
"description": "The admin endpoint",
"audience": [
"internal"
]
}
}
},
{
"endpoint": "/no-audience",
"extra_config": {
"documentation/openapi": {
"description": "An endpoint without audience"
}
}
}
]
Then, when generating the documentation, you can filter out the /admin endpoint and exclude it from the final documentation with krakend openapi export -c krakend.json -a public. The command would document /user, /cart, and /no-audience.
When you filter by audience, endpoints without an audience always appear in the final documentation.
Similarly, krakend openapi export -c krakend.json -a internal generates the documentation for all the endpoints, which is the same result you get without the -a flag.
The audience attribute only excludes endpoints from the final documentation. The endpoints still exist in the service, and you must protect them against unwanted usage.
Documenting response examples and errors
The response_definition object allows you to set examples of the response an API endpoint will deliver. For instance:
{
"endpoint": "/cart",
"extra_config": {
"documentation/openapi": {
"description": "The cart endpoint",
"response_definition": {
"200": {
"example": {
"status": "OK",
"message": "Product added to the cart!"
}
},
"500": {
"example": {
"status": "KO",
"message": "Couldn't add the product to the cart!"
}
}
}
}
}
}
When the examples are long, you might want to keep the example responses in a separate file (like settings or partials) using Flexible Configuration, so the endpoint template stays readable. For instance:
{
"endpoint": "/cart",
"extra_config": {
"documentation/openapi": {
"description": "The cart endpoint",
"response_definition": {
"200": {
"example": {{- include "openapi_cart_response.json" -}}
}
}
}
}
}
You can also describe the response with example_schema, a JSON schema written as an object or encoded in base64. Use either example or example_schema, but not both (if you set both, the schema takes precedence). Flexible Configuration saves you from writing base64 by hand. For instance:
{
"endpoint": "/cart",
"extra_config": {
"documentation/openapi": {
"description": "The cart endpoint",
"response_definition": {
"200": {
"example_schema": {{ include "cart_schema.json" | b64enc | toJson }}
}
}
}
}
}
Or writing the schema inline, escaped with backticks:
{
"endpoint": "/cart",
"extra_config": {
"documentation/openapi": {
"description": "The cart endpoint",
"response_definition": {
"200": {
"example_schema": "{{ `{
"type": "object",
"title": "This is the response"
}` | b64enc }}"
}
}
}
}
}
