mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-22 09:36:49 +03:00
Add OpenAPIRenderer by default, and add schema docs. (#6233)
* Add OpenAPIRenderer as a default for get_schema_view, and start adding schema docs * Add optional pyyaml * Updating schema docs
This commit is contained in:
parent
18ad3290ef
commit
6522d4ae20
|
@ -10,12 +10,50 @@ API schemas are a useful tool that allow for a range of use cases, including
|
||||||
generating reference documentation, or driving dynamic client libraries that
|
generating reference documentation, or driving dynamic client libraries that
|
||||||
can interact with your API.
|
can interact with your API.
|
||||||
|
|
||||||
## Install Core API
|
## Install Core API & PyYAML
|
||||||
|
|
||||||
You'll need to install the `coreapi` package in order to add schema support
|
You'll need to install the `coreapi` package in order to add schema support
|
||||||
for REST framework.
|
for REST framework. You probably also want to install `pyyaml`, so that you
|
||||||
|
can render the schema into the commonly used YAML-based OpenAPI format.
|
||||||
|
|
||||||
pip install coreapi
|
pip install coreapi pyyaml
|
||||||
|
|
||||||
|
## Quickstart
|
||||||
|
|
||||||
|
There are two different ways you can serve a schema description for you API.
|
||||||
|
|
||||||
|
### Generating a schema with the `generateschema` management command
|
||||||
|
|
||||||
|
To generate a static API schema, use the `generateschema` management command.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ python manage.py generateschema > schema.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
Once you've generated a schema in this way you can annotate it with any
|
||||||
|
additional information that cannot be automatically inferred by the schema
|
||||||
|
generator.
|
||||||
|
|
||||||
|
You might want to check your API schema into version control and update it
|
||||||
|
with each new release, or serve the API schema from your site's static media.
|
||||||
|
|
||||||
|
### Adding a view with `get_schema_view`
|
||||||
|
|
||||||
|
To add a dynamically generated schema view to your API, use `get_schema_view`.
|
||||||
|
|
||||||
|
```python
|
||||||
|
from rest_framework.schemas import get_schema_view
|
||||||
|
|
||||||
|
schema_view = get_schema_view(title="Example API")
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url('^schema$', schema_view),
|
||||||
|
...
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
See below [for more details](#the-get_schema_view-shortcut) on customizing a
|
||||||
|
dynamically generated schema view.
|
||||||
|
|
||||||
## Internal schema representation
|
## Internal schema representation
|
||||||
|
|
||||||
|
@ -71,38 +109,19 @@ endpoint:
|
||||||
In order to be presented in an HTTP response, the internal representation
|
In order to be presented in an HTTP response, the internal representation
|
||||||
has to be rendered into the actual bytes that are used in the response.
|
has to be rendered into the actual bytes that are used in the response.
|
||||||
|
|
||||||
|
REST framework includes a few different renderers that you can use for
|
||||||
|
encoding the API schema.
|
||||||
|
|
||||||
|
* `renderers.OpenAPIRenderer` - Renders into YAML-based [OpenAPI][openapi], the most widely used API schema format.
|
||||||
|
* `renderers.JSONOpenAPIRenderer` - Renders into JSON-based [OpenAPI][openapi].
|
||||||
|
* `renderers.CoreJSONRenderer` - Renders into [Core JSON][corejson], a format designed for
|
||||||
|
use with the `coreapi` client library.
|
||||||
|
|
||||||
|
|
||||||
[Core JSON][corejson] is designed as a canonical format for use with Core API.
|
[Core JSON][corejson] is designed as a canonical format for use with Core API.
|
||||||
REST framework includes a renderer class for handling this media type, which
|
REST framework includes a renderer class for handling this media type, which
|
||||||
is available as `renderers.CoreJSONRenderer`.
|
is available as `renderers.CoreJSONRenderer`.
|
||||||
|
|
||||||
### Alternate schema formats
|
|
||||||
|
|
||||||
Other schema formats such as [Open API][open-api] ("Swagger"),
|
|
||||||
[JSON HyperSchema][json-hyperschema], or [API Blueprint][api-blueprint] can also
|
|
||||||
be supported by implementing a custom renderer class that handles converting a
|
|
||||||
`Document` instance into a bytestring representation.
|
|
||||||
|
|
||||||
If there is a Core API codec package that supports encoding into the format you
|
|
||||||
want to use then implementing the renderer class can be done by using the codec.
|
|
||||||
|
|
||||||
#### Example
|
|
||||||
|
|
||||||
For example, the `openapi_codec` package provides support for encoding or decoding
|
|
||||||
to the Open API ("Swagger") format:
|
|
||||||
|
|
||||||
from rest_framework import renderers
|
|
||||||
from openapi_codec import OpenAPICodec
|
|
||||||
|
|
||||||
class SwaggerRenderer(renderers.BaseRenderer):
|
|
||||||
media_type = 'application/openapi+json'
|
|
||||||
format = 'swagger'
|
|
||||||
|
|
||||||
def render(self, data, media_type=None, renderer_context=None):
|
|
||||||
codec = OpenAPICodec()
|
|
||||||
return codec.dump(data)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Schemas vs Hypermedia
|
## Schemas vs Hypermedia
|
||||||
|
|
||||||
|
@ -325,13 +344,12 @@ ROOT_URLCONF setting.
|
||||||
May be used to pass the set of renderer classes that can be used to render the API root endpoint.
|
May be used to pass the set of renderer classes that can be used to render the API root endpoint.
|
||||||
|
|
||||||
from rest_framework.schemas import get_schema_view
|
from rest_framework.schemas import get_schema_view
|
||||||
from rest_framework.renderers import CoreJSONRenderer
|
from rest_framework.renderers import JSONOpenAPIRenderer
|
||||||
from my_custom_package import APIBlueprintRenderer
|
|
||||||
|
|
||||||
schema_view = get_schema_view(
|
schema_view = get_schema_view(
|
||||||
title='Server Monitoring API',
|
title='Server Monitoring API',
|
||||||
url='https://www.example.org/api/',
|
url='https://www.example.org/api/',
|
||||||
renderer_classes=[CoreJSONRenderer, APIBlueprintRenderer]
|
renderer_classes=[JSONOpenAPIRenderer]
|
||||||
)
|
)
|
||||||
|
|
||||||
#### `patterns`
|
#### `patterns`
|
||||||
|
@ -364,7 +382,6 @@ Defaults to `settings.DEFAULT_AUTHENTICATION_CLASSES`
|
||||||
May be used to specify the list of permission classes that will apply to the schema endpoint.
|
May be used to specify the list of permission classes that will apply to the schema endpoint.
|
||||||
Defaults to `settings.DEFAULT_PERMISSION_CLASSES`
|
Defaults to `settings.DEFAULT_PERMISSION_CLASSES`
|
||||||
|
|
||||||
|
|
||||||
## Using an explicit schema view
|
## Using an explicit schema view
|
||||||
|
|
||||||
If you need a little more control than the `get_schema_view()` shortcut gives you,
|
If you need a little more control than the `get_schema_view()` shortcut gives you,
|
||||||
|
@ -386,7 +403,7 @@ return the schema.
|
||||||
generator = schemas.SchemaGenerator(title='Bookings API')
|
generator = schemas.SchemaGenerator(title='Bookings API')
|
||||||
|
|
||||||
@api_view()
|
@api_view()
|
||||||
@renderer_classes([renderers.CoreJSONRenderer])
|
@renderer_classes([renderers.OpenAPIRenderer])
|
||||||
def schema_view(request):
|
def schema_view(request):
|
||||||
schema = generator.get_schema(request)
|
schema = generator.get_schema(request)
|
||||||
return response.Response(schema)
|
return response.Response(schema)
|
||||||
|
@ -408,7 +425,7 @@ In order to present a schema with endpoints filtered by user permissions,
|
||||||
you need to pass the `request` argument to the `get_schema()` method, like so:
|
you need to pass the `request` argument to the `get_schema()` method, like so:
|
||||||
|
|
||||||
@api_view()
|
@api_view()
|
||||||
@renderer_classes([renderers.CoreJSONRenderer])
|
@renderer_classes([renderers.OpenAPIRenderer])
|
||||||
def schema_view(request):
|
def schema_view(request):
|
||||||
generator = schemas.SchemaGenerator(title='Bookings API')
|
generator = schemas.SchemaGenerator(title='Bookings API')
|
||||||
return response.Response(generator.get_schema(request=request))
|
return response.Response(generator.get_schema(request=request))
|
||||||
|
@ -432,21 +449,10 @@ representation.
|
||||||
)
|
)
|
||||||
|
|
||||||
@api_view()
|
@api_view()
|
||||||
@renderer_classes([renderers.CoreJSONRenderer])
|
@renderer_classes([renderers.OpenAPIRenderer])
|
||||||
def schema_view(request):
|
def schema_view(request):
|
||||||
return response.Response(schema)
|
return response.Response(schema)
|
||||||
|
|
||||||
## Static schema file
|
|
||||||
|
|
||||||
A final option is to write your API schema as a static file, using one
|
|
||||||
of the available formats, such as Core JSON or Open API.
|
|
||||||
|
|
||||||
You could then either:
|
|
||||||
|
|
||||||
* Write a schema definition as a static file, and [serve the static file directly][static-files].
|
|
||||||
* Write a schema definition that is loaded using `Core API`, and then
|
|
||||||
rendered to one of many available formats, depending on the client request.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Schemas as documentation
|
# Schemas as documentation
|
||||||
|
@ -535,7 +541,7 @@ Arguments:
|
||||||
Returns a `coreapi.Document` instance that represents the API schema.
|
Returns a `coreapi.Document` instance that represents the API schema.
|
||||||
|
|
||||||
@api_view
|
@api_view
|
||||||
@renderer_classes([renderers.CoreJSONRenderer])
|
@renderer_classes([renderers.OpenAPIRenderer])
|
||||||
def schema_view(request):
|
def schema_view(request):
|
||||||
generator = schemas.SchemaGenerator(title='Bookings API')
|
generator = schemas.SchemaGenerator(title='Bookings API')
|
||||||
return Response(generator.get_schema())
|
return Response(generator.get_schema())
|
||||||
|
|
|
@ -5,3 +5,4 @@ django-guardian==1.4.9
|
||||||
django-filter==1.1.0
|
django-filter==1.1.0
|
||||||
coreapi==2.3.1
|
coreapi==2.3.1
|
||||||
coreschema==0.0.4
|
coreschema==0.0.4
|
||||||
|
pyyaml
|
||||||
|
|
|
@ -19,13 +19,12 @@ class SchemaView(APIView):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(SchemaView, self).__init__(*args, **kwargs)
|
super(SchemaView, self).__init__(*args, **kwargs)
|
||||||
if self.renderer_classes is None:
|
if self.renderer_classes is None:
|
||||||
|
self.renderer_classes = [
|
||||||
|
renderers.OpenAPIRenderer,
|
||||||
|
renderers.CoreJSONRenderer
|
||||||
|
]
|
||||||
if renderers.BrowsableAPIRenderer in api_settings.DEFAULT_RENDERER_CLASSES:
|
if renderers.BrowsableAPIRenderer in api_settings.DEFAULT_RENDERER_CLASSES:
|
||||||
self.renderer_classes = [
|
self.renderer_classes += [renderers.BrowsableAPIRenderer]
|
||||||
renderers.CoreJSONRenderer,
|
|
||||||
renderers.BrowsableAPIRenderer,
|
|
||||||
]
|
|
||||||
else:
|
|
||||||
self.renderer_classes = [renderers.CoreJSONRenderer]
|
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
schema = self.schema_generator.get_schema(request, self.public)
|
schema = self.schema_generator.get_schema(request, self.public)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user