Generate the OpenAPI schema and a typed client¶
djangocms-rest is fully typed and can emit an OpenAPI 3 schema for every endpoint — including a JSON-schema description of each installed plugin. With drf-spectacular you get browsable docs (Swagger UI / ReDoc) and a schema you can feed to a client generator for a type-safe frontend.
Steps¶
Install drf-spectacular:
pip install drf-spectacular
Register it as the schema class and add it to
INSTALLED_APPS:# settings.py INSTALLED_APPS = [ # ... "drf_spectacular", ] REST_FRAMEWORK = { "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema", } SPECTACULAR_SETTINGS = { "TITLE": "My project API", "DESCRIPTION": "Headless django CMS content API", # Reported as `info.version` in the schema. Use *your* project's API # version — tying it to a constant keeps it in step with releases: # from myproject import __version__ # "VERSION": __version__, "VERSION": "1.0.0", "SERVE_INCLUDE_SCHEMA": False, }
Note
VERSIONis your API’s version, not the djangocms-rest version. (djangocms-rest’s own test project happens to set"VERSION": djangocms_rest.__version__— that’s a convenient pattern for tracking a constant, not a value you should copy verbatim.)Expose the schema and documentation views:
# urls.py from drf_spectacular.views import ( SpectacularAPIView, SpectacularJSONAPIView, SpectacularSwaggerView, SpectacularRedocView, ) urlpatterns += [ path("api/schema/", SpectacularAPIView.as_view(), name="schema"), path("api/schema-json/", SpectacularJSONAPIView.as_view(), name="schema-json"), path("api/docs/", SpectacularSwaggerView.as_view(url_name="schema"), name="swagger-ui"), path("api/redoc/", SpectacularRedocView.as_view(url_name="schema"), name="redoc"), ]
Verify¶
Browsable docs:
http://localhost:8080/api/docs/(Swagger UI) andhttp://localhost:8080/api/redoc/(ReDoc).Raw schema:
http://localhost:8080/api/schema-json/.
Generate a typed client¶
Point a generator at the schema URL. For TypeScript, @hey-api/openapi-ts produces a client and types (and can integrate Zod for runtime validation):
npx @hey-api/openapi-ts \
-i http://localhost:8080/api/schema-json/ \
-o src/client
Note
Operation ids — and therefore generated function/type names — follow the mount point
you chose in urls.py. If you mount the API under api/cms/, RetrieveLanguages
becomes CmsRetrieveLanguages. Choose the mount point before you generate clients to
avoid churn.
Typing plugin content¶
Plugin payloads are dynamic, so their detailed shape comes from the
/api/plugins/ endpoint rather than the static schema. To get rich,
fully typed plugin properties, declare a serializer_class on your plugins — see
Serialize plugins (default and custom).
See also
Reference — the endpoints the schema describes.
Plugin serialization — how plugin definitions are derived.