Skip to content

Commit 6522d4a

Browse files
authored
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
1 parent 18ad329 commit 6522d4a

File tree

3 files changed

+62
-56
lines changed

3 files changed

+62
-56
lines changed

docs/api-guide/schemas.md

Lines changed: 56 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,50 @@ API schemas are a useful tool that allow for a range of use cases, including
1010
generating reference documentation, or driving dynamic client libraries that
1111
can interact with your API.
1212

13-
## Install Core API
13+
## Install Core API & PyYAML
1414

1515
You'll need to install the `coreapi` package in order to add schema support
16-
for REST framework.
16+
for REST framework. You probably also want to install `pyyaml`, so that you
17+
can render the schema into the commonly used YAML-based OpenAPI format.
1718

18-
pip install coreapi
19+
pip install coreapi pyyaml
20+
21+
## Quickstart
22+
23+
There are two different ways you can serve a schema description for you API.
24+
25+
### Generating a schema with the `generateschema` management command
26+
27+
To generate a static API schema, use the `generateschema` management command.
28+
29+
```shell
30+
$ python manage.py generateschema > schema.yml
31+
```
32+
33+
Once you've generated a schema in this way you can annotate it with any
34+
additional information that cannot be automatically inferred by the schema
35+
generator.
36+
37+
You might want to check your API schema into version control and update it
38+
with each new release, or serve the API schema from your site's static media.
39+
40+
### Adding a view with `get_schema_view`
41+
42+
To add a dynamically generated schema view to your API, use `get_schema_view`.
43+
44+
```python
45+
from rest_framework.schemas import get_schema_view
46+
47+
schema_view = get_schema_view(title="Example API")
48+
49+
urlpatterns = [
50+
url('^schema$', schema_view),
51+
...
52+
]
53+
```
54+
55+
See below [for more details](#the-get_schema_view-shortcut) on customizing a
56+
dynamically generated schema view.
1957

2058
## Internal schema representation
2159

@@ -71,37 +109,18 @@ endpoint:
71109
In order to be presented in an HTTP response, the internal representation
72110
has to be rendered into the actual bytes that are used in the response.
73111

74-
[Core JSON][corejson] is designed as a canonical format for use with Core API.
75-
REST framework includes a renderer class for handling this media type, which
76-
is available as `renderers.CoreJSONRenderer`.
77-
78-
### Alternate schema formats
79-
80-
Other schema formats such as [Open API][open-api] ("Swagger"),
81-
[JSON HyperSchema][json-hyperschema], or [API Blueprint][api-blueprint] can also
82-
be supported by implementing a custom renderer class that handles converting a
83-
`Document` instance into a bytestring representation.
84-
85-
If there is a Core API codec package that supports encoding into the format you
86-
want to use then implementing the renderer class can be done by using the codec.
87-
88-
#### Example
89-
90-
For example, the `openapi_codec` package provides support for encoding or decoding
91-
to the Open API ("Swagger") format:
92-
93-
from rest_framework import renderers
94-
from openapi_codec import OpenAPICodec
95-
96-
class SwaggerRenderer(renderers.BaseRenderer):
97-
media_type = 'application/openapi+json'
98-
format = 'swagger'
112+
REST framework includes a few different renderers that you can use for
113+
encoding the API schema.
99114

100-
def render(self, data, media_type=None, renderer_context=None):
101-
codec = OpenAPICodec()
102-
return codec.dump(data)
115+
* `renderers.OpenAPIRenderer` - Renders into YAML-based [OpenAPI][openapi], the most widely used API schema format.
116+
* `renderers.JSONOpenAPIRenderer` - Renders into JSON-based [OpenAPI][openapi].
117+
* `renderers.CoreJSONRenderer` - Renders into [Core JSON][corejson], a format designed for
118+
use with the `coreapi` client library.
103119

104120

121+
[Core JSON][corejson] is designed as a canonical format for use with Core API.
122+
REST framework includes a renderer class for handling this media type, which
123+
is available as `renderers.CoreJSONRenderer`.
105124

106125

107126
## Schemas vs Hypermedia
@@ -325,13 +344,12 @@ ROOT_URLCONF setting.
325344
May be used to pass the set of renderer classes that can be used to render the API root endpoint.
326345

327346
from rest_framework.schemas import get_schema_view
328-
from rest_framework.renderers import CoreJSONRenderer
329-
from my_custom_package import APIBlueprintRenderer
347+
from rest_framework.renderers import JSONOpenAPIRenderer
330348

331349
schema_view = get_schema_view(
332350
title='Server Monitoring API',
333351
url='https://www.example.org/api/',
334-
renderer_classes=[CoreJSONRenderer, APIBlueprintRenderer]
352+
renderer_classes=[JSONOpenAPIRenderer]
335353
)
336354

337355
#### `patterns`
@@ -364,7 +382,6 @@ Defaults to `settings.DEFAULT_AUTHENTICATION_CLASSES`
364382
May be used to specify the list of permission classes that will apply to the schema endpoint.
365383
Defaults to `settings.DEFAULT_PERMISSION_CLASSES`
366384

367-
368385
## Using an explicit schema view
369386

370387
If you need a little more control than the `get_schema_view()` shortcut gives you,
@@ -386,7 +403,7 @@ return the schema.
386403
generator = schemas.SchemaGenerator(title='Bookings API')
387404

388405
@api_view()
389-
@renderer_classes([renderers.CoreJSONRenderer])
406+
@renderer_classes([renderers.OpenAPIRenderer])
390407
def schema_view(request):
391408
schema = generator.get_schema(request)
392409
return response.Response(schema)
@@ -408,7 +425,7 @@ In order to present a schema with endpoints filtered by user permissions,
408425
you need to pass the `request` argument to the `get_schema()` method, like so:
409426

410427
@api_view()
411-
@renderer_classes([renderers.CoreJSONRenderer])
428+
@renderer_classes([renderers.OpenAPIRenderer])
412429
def schema_view(request):
413430
generator = schemas.SchemaGenerator(title='Bookings API')
414431
return response.Response(generator.get_schema(request=request))
@@ -432,21 +449,10 @@ representation.
432449
)
433450

434451
@api_view()
435-
@renderer_classes([renderers.CoreJSONRenderer])
452+
@renderer_classes([renderers.OpenAPIRenderer])
436453
def schema_view(request):
437454
return response.Response(schema)
438455

439-
## Static schema file
440-
441-
A final option is to write your API schema as a static file, using one
442-
of the available formats, such as Core JSON or Open API.
443-
444-
You could then either:
445-
446-
* Write a schema definition as a static file, and [serve the static file directly][static-files].
447-
* Write a schema definition that is loaded using `Core API`, and then
448-
rendered to one of many available formats, depending on the client request.
449-
450456
---
451457

452458
# Schemas as documentation
@@ -535,7 +541,7 @@ Arguments:
535541
Returns a `coreapi.Document` instance that represents the API schema.
536542

537543
@api_view
538-
@renderer_classes([renderers.CoreJSONRenderer])
544+
@renderer_classes([renderers.OpenAPIRenderer])
539545
def schema_view(request):
540546
generator = schemas.SchemaGenerator(title='Bookings API')
541547
return Response(generator.get_schema())

requirements/requirements-optionals.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ django-guardian==1.4.9
55
django-filter==1.1.0
66
coreapi==2.3.1
77
coreschema==0.0.4
8+
pyyaml

rest_framework/schemas/views.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,12 @@ class SchemaView(APIView):
1919
def __init__(self, *args, **kwargs):
2020
super(SchemaView, self).__init__(*args, **kwargs)
2121
if self.renderer_classes is None:
22+
self.renderer_classes = [
23+
renderers.OpenAPIRenderer,
24+
renderers.CoreJSONRenderer
25+
]
2226
if renderers.BrowsableAPIRenderer in api_settings.DEFAULT_RENDERER_CLASSES:
23-
self.renderer_classes = [
24-
renderers.CoreJSONRenderer,
25-
renderers.BrowsableAPIRenderer,
26-
]
27-
else:
28-
self.renderer_classes = [renderers.CoreJSONRenderer]
27+
self.renderer_classes += [renderers.BrowsableAPIRenderer]
2928

3029
def get(self, request, *args, **kwargs):
3130
schema = self.schema_generator.get_schema(request, self.public)

0 commit comments

Comments
 (0)