Skip to content
On this page

Publishing to OpenAPI

You can convert CDS models to the OpenAPI Specification, a widely adopted API description standard.

Usage from CLI

For example, this is how you convert all services in srv/ and store the API files in the docs/ folder:

sh
cds compile srv --service all -o docs --to openapi
cds compile srv --service all -o docs --to openapi

With the --openapi:diagram parameter, you can also include a yuml ER diagram of the service entities in the Open API file.

openapi

The default value of the server URL is the service base path as declared in the CDS source.

If you have a single server and you want to set the server URL, use --openapi:url <Server URL for Open API export> option. Include the service path in the URL. For that, you can use the ${service-path} variable.

If you want to configure multiple servers, you can use --openapi:servers <JSON_Object_defining_servers> which accepts stringified JSON of the server object. Here, you can pass multiple server objects by passing the stringified JSON objects as an array.

sh
cds compile srv service.cds --to openapi --openapi:servers "\"'[{\\\"url\\\":\\\"api.sandbox.com\\\",\\\"description\\\":\\\"Test URL\\\"},{\\\"url\\\":\\\"api.prod.com\\\",\\\"description\\\":\\\"Production URL\\\"}]'\""
cds compile srv service.cds --to openapi --openapi:servers "\"'[{\\\"url\\\":\\\"api.sandbox.com\\\",\\\"description\\\":\\\"Test URL\\\"},{\\\"url\\\":\\\"api.prod.com\\\",\\\"description\\\":\\\"Production URL\\\"}]'\""

Note: --openapi:url is ignored when this option is specified.

Swagger UI

Embedded in Node.js

In Node.js apps, the standard Swagger UI can be served with the help of the cds-swagger-ui-express package:

sh
npm add --save-dev cds-swagger-ui-express
npm add --save-dev cds-swagger-ui-express

You need a server.js file to integrate it in the bootstrap process:

js
const cds = require ('@sap/cds')
module.exports = cds.server

if (process.env.NODE_ENV !== 'production') {
  const cds_swagger = require ('cds-swagger-ui-express')
  cds.on ('bootstrap', app => app.use (cds_swagger()) )
}
const cds = require ('@sap/cds')
module.exports = cds.server

if (process.env.NODE_ENV !== 'production') {
  const cds_swagger = require ('cds-swagger-ui-express')
  cds.on ('bootstrap', app => app.use (cds_swagger()) )
}

Swagger UI is then served at $api-docs/.... Just follow the Open API preview links on the index page: Swagger link

Learn more about the cds-swagger-ui-express.

Embedded in Java

Swagger UI is not available out of the box for CAP Java. However, check out this commit in our CAP Java sample application that demonstrates how to integrate a Swagger UI into your Spring Boot application.

Online Swagger Editor

Alternatively, you can use the online Swagger editor with the OpenAPI files produced with the CLI. In this case, you likely need to enable CORS because the swagger.io site needs to call localhost. You can use the cors middleware, for example.

Annotations

The OData to OpenAPI Mapping can be fine-tuned via annotations in the CSDL ($metadata) documents.

See Frequently Asked Questions for examples on how to use these annotations.

Core Annotations

TermAnnotation TargetOpenAPI field
ComputedPropertyomit from Create and Update structures
DefaultNamespaceSchemapath templates for actions and functions without namespace prefix
DescriptionAction, ActionImport, Function, FunctionImportsummary of Operation Object
DescriptionEntitySet, Singletondescription of Tag Object
DescriptionEntityTypedescription of Request Body Object
DescriptionComplexType, EntityType, EnumerationType, Parameter, Property, TypeDefinitiondescription of Schema Object
DescriptionSchema, EntityContainerinfo.title
ExamplePropertyexample of Schema Object
ImmutablePropertyomit from Update structure
LongDescriptionAction, ActionImport, Function, FunctionImportdescription of Operation Object
LongDescriptionSchema, EntityContainerinfo.description
Permissions:ReadPropertyomit read-only properties from Create and Update structures
SchemaVersionSchemainfo.version

Capabilities

TermAnnotation TargetOpenAPI field
CountRestrictions
/Countable
EntitySet$count system query option for GET operation
DeleteRestrictions
/Deletable
EntitySet, SingletonDELETE operation for deleting an existing entity
/DescriptionEntitySet, Singletonsummary of Operation Object
/LongDescriptionEntitySet, Singletondescription of Operation Object
ExpandRestrictions
/Expandable
EntitySet, Singleton$expand system query option for GET operations
FilterRestrictions
/Filterable
EntitySet$filter system query option for GET operation
/RequiredPropertiesEntitySetrequired properties in $filter system query option for GET operation (parameter description only)
/RequiresFilterEntitySet$filter system query option for GET operation is required
IndexableByKeyEntitySetGET, PATCH, and DELETE operations for a single entity within an entity set
InsertRestrictions
/Insertable
EntitySetPOST operation for inserting a new entity
/DescriptionEntitySetsummary of Operation Object
/LongDescriptionEntitySetdescription of Operation Object
KeyAsSegmentSupportedEntityContainerpaths URL templates use key-as-segment style instead of parenthesis style
NavigationRestrictions
/RestrictedProperties
EntitySet, Singletonoperations via a navigation path
  /DeleteRestrictions/...EntitySet, SingletonDELETE operation for deleting a contained entity via a navigation path
  /FilterRestrictions/...EntitySet, Singleton$filter system query option for reading related entities via a navigation path
  /InsertRestrictions/...EntitySet, SingletonPOST operation for inserting a new related entity via a navigation path
  /ReadByKeyRestrictions/...EntitySet, SingletonGET operation for reading a contained entity by key via a navigation path
  /ReadRestrictions/...EntitySet, SingletonGET operation for reading related entities via a navigation path
  /SearchRestrictions/...EntitySet, Singleton$search system query option for reading related entities via a navigation path
  /SelectSupport/...EntitySet, Singleton$select system query option for reading related entities via a navigation path
  /SkipSupportedEntitySet, Singleton$skip system query option for reading contained entities via a navigation path
  /SortRestrictions/...EntitySet, Singleton$orderby system query option for reading related entities via a navigation path
  /TopSupportedEntitySet, Singleton$top system query option for reading contained entities via a navigation path
  /UpdateRestrictions/...EntitySet, SingletonPATCH operation for modifying a contained entity via a navigation path
ReadByKeyRestrictions
/Readable
EntitySetGET operation for reading a single entity by key
/DescriptionEntitySetsummary of Operation Object
/LongDescriptionEntitySetdescription of Operation Object
ReadRestrictions
/Readable
EntitySet, SingletonGET operation for reading an entity set or singleton
/DescriptionEntitySet, Singletonsummary of Operation Object
/LongDescriptionEntitySet, Singletondescription of Operation Object
SearchRestrictions
/Searchable
EntitySet$search system query option for GET operation
SelectSupport
/Supported
EntitySet, Singleton$select system query option for GET operation
SkipSupportedEntitySet$skip system query option for GET operation
SortRestrictions
/NonSortableProperties
EntitySetproperties not listed in $orderby system query option for GET operation
/SortableEntitySet$orderby system query option for GET operation
TopSupportedEntitySet$top system query option for GET operation
UpdateRestrictions
/Updatable
EntitySet, SingletonPATCH operation for modifying an existing entity
/DescriptionEntitySet, Singletonsummary of Operation Object
/LongDescriptionEntitySet, Singletondescription of Operation Object
BatchSupport
/Supported
EntityContainerBatch Support for the service

Validation

TermAnnotation TargetOpenAPI field
AllowedValuesPropertyenum of Schema Object - list of allowed (string) values
ExclusivePropertyexclusiveMinimum/exclusiveMaximum of Schema Object
MaximumPropertymaximum of Schema Object
MinimumPropertyminimum of Schema Object
PatternPropertypattern of Schema Object

Authorization

TermAnnotation TargetOpenAPI field
AuthorizationsEntityContainersecuritySchemes of Components Object/securityDefinitions of Swagger Object
SecuritySchemesEntityContainersecurity of OpenAPI/Swagger Object

Frequently Asked Questions

Examples for typical questions on how to fine-tune the generated OpenAPI descriptions.

How do I suppress GET (list and by-key) on an entity set?

To suppress both types of GET requests to an entity set, annotate it with

json
"@Capabilities.ReadRestrictions": {
    "Readable": false
}
"@Capabilities.ReadRestrictions": {
    "Readable": false
}

How do I suppress GET (list) on an entity set?

To suppress only GET list requests to an entity set and still allow GET by-key, annotate it with

json
"@Capabilities.ReadRestrictions": {
    "Readable": false,
    "ReadByKeyRestrictions": {
        "Readable": true
    }
}
"@Capabilities.ReadRestrictions": {
    "Readable": false,
    "ReadByKeyRestrictions": {
        "Readable": true
    }
}

How do I suppress GET (by-key) on an entity set?

To suppress only GET by-key requests to an entity set and still allow GET list, annotate it with

json
"@Capabilities.ReadRestrictions": {
    "ReadByKeyRestrictions": {
        "Readable": false
    }
}
"@Capabilities.ReadRestrictions": {
    "ReadByKeyRestrictions": {
        "Readable": false
    }
}