Skip to content

Commit e57ec35

Browse files
committed
Schemas API Guide page.
1 parent fe1e877 commit e57ec35

File tree

2 files changed

+174
-11
lines changed

2 files changed

+174
-11
lines changed

docs/api-guide/schemas.md

Lines changed: 173 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,49 @@
1+
source: schemas.py
2+
13
# Schema
24

5+
> A machine-readable [schema] describes what resources are available via the API, what their URLs are, how they are represented and what operations they support.
6+
>
7+
> — Heroku, [JSON Schema for the Heroku Platform API][cite]
8+
9+
API schemas are a useful tool that allow for a range of use cases, including
10+
generating reference documentation, or driving dynamic client libraries that
11+
can interact with your API.
12+
13+
Django REST Framework provides support for automatic generation of
14+
[OpenAPI][openapi] schemas.
15+
316
## Generating an OpenAPI Schema
417

5-
### Static
18+
### Install `pyyaml`
19+
20+
You'll need to install `pyyaml`, so that you can render your generated schema
21+
into the commonly used YAML-based OpenAPI format.
22+
23+
pip install pyyaml
24+
25+
### Generating a static schema with the `generateschema` management command
626

727
If your schema is static, you can use the `generateschema` management command:
828

929
```bash
1030
./manage.py generateschema > openapi-schema.yml
1131
```
1232

13-
### Dynamic
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+
### Generating a dynamic schema with `SchemaView`
1441

15-
If you require a dynamic schema, because foreign key choices depend on database values, for example, you can route a `SchemaView` that will generate and serve you schema on demand.
42+
If you require a dynamic schema, because foreign key choices depend on database
43+
values, for example, you can route a `SchemaView` that will generate and serve
44+
your schema on demand.
45+
46+
To route a `SchemaView`, use the `get_schema_view()` helper.
1647

1748
In `urls.py`:
1849

@@ -34,19 +65,151 @@ urlpatterns = [
3465

3566
#### `get_schema_view()`
3667

37-
* ...
68+
The `get_schema_view()` helper takes the following keyword arguments:
69+
70+
* `title`: May be used to provide a descriptive title for the schema definition.
71+
* `description`: Longer descriptive text.
72+
* `url`: May be used to pass a canonical base URL for the schema.
73+
74+
schema_view = get_schema_view(
75+
title='Server Monitoring API',
76+
url='https://www.example.org/api/'
77+
)
78+
79+
* `urlconf`: A string representing the import path to the URL conf that you want
80+
to generate an API schema for. This defaults to the value of Django's
81+
`ROOT_URLCONF` setting.
82+
83+
schema_view = get_schema_view(
84+
title='Server Monitoring API',
85+
url='https://www.example.org/api/',
86+
urlconf='myproject.urls'
87+
)
88+
* `patterns`: List of url patterns to limit the schema introspection to. If you
89+
only want the `myproject.api` urls to be exposed in the schema:
90+
91+
schema_url_patterns = [
92+
url(r'^api/', include('myproject.api.urls')),
93+
]
94+
95+
schema_view = get_schema_view(
96+
title='Server Monitoring API',
97+
url='https://www.example.org/api/',
98+
patterns=schema_url_patterns,
99+
)
100+
101+
* `generator_class`: May be used to specify a `SchemaGenerator` subclass to be
102+
passed to the `SchemaView`.
103+
* `authentication_classes`: May be used to specify the list of authentication
104+
classes that will apply to the schema endpoint. Defaults to
105+
`settings.DEFAULT_AUTHENTICATION_CLASSES`
106+
* `permission_classes`: May be used to specify the list of permission classes
107+
that will apply to the schema endpoint. Defaults to
108+
`settings.DEFAULT_PERMISSION_CLASSES`.
109+
* `renderer_classes`: May be used to pass the set of renderer classes that can
110+
be used to render the API root endpoint.
38111

39-
* ...
40112

41-
* ...
113+
## Customizing Schema Generation
42114

115+
You may customize schema generation at the level of the schema as a whole, or
116+
on a per-view basis.
43117

118+
### Schema Level Customization
44119

45-
## Customizing Schema Generation
120+
In order to customize the top-level schema sublass
121+
`rest_framework.schemas.openapi.SchemaGenerator` and provide it as an argument
122+
to the `generateschema` command or `get_schema_view()` helper function.
46123

47-
### Schema Level Customization
124+
#### SchemaGenerator
125+
126+
A class that walks a list of routed URL patterns, requests the schema for each
127+
view and collates the resulting OpenAPI schema.
128+
129+
Typically you'll instantiate `SchemaGenerator` with a `title` argument, like so:
130+
131+
generator = SchemaGenerator(title='Stock Prices API')
132+
133+
Arguments:
134+
135+
* `title` **required**: The name of the API.
136+
* `description`: Longer descriptive text.
137+
* `url`: The root URL of the API schema. This option is not required unless the schema is included under path prefix.
138+
* `patterns`: A list of URLs to inspect when generating the schema. Defaults to the project's URL conf.
139+
* `urlconf`: A URL conf module name to use when generating the schema. Defaults to `settings.ROOT_URLCONF`.
140+
141+
##### get_schema(self, request)
142+
143+
Returns a dictionary that represents the OpenAPI schema:
144+
145+
generator = SchemaGenerator(title='Stock Prices API')
146+
schema = generator.get_schema()
147+
148+
The `request` argument is optional, and may be used if you want to apply
149+
per-user permissions to the resulting schema generation.
150+
151+
This is a good point to override if you want to customise the generated
152+
dictionary, for example to add custom
153+
[specification extensions][openapi-specification-extensions].
48154

49155
### Per-View Customization
50156

51-
* Subclass `rest_framework.schemas.openapi.AutoSchema`.
52-
* Override `get_operations()`.
157+
By default, view introspection is performed by an `AutoSchema` instance
158+
accessible via the `schema` attribute on `APIView`. This provides the
159+
appropriate [Open API operation object][openapi-operation] for the view,
160+
request method and path:
161+
162+
auto_schema = view.schema
163+
operation = auto_schema.get_operation(...)
164+
165+
In compiling the schema, `SchemaGenerator` calls `view.schema.get_operation()`
166+
for each view, allowed method, and path.
167+
168+
---
169+
170+
**Note**: For basic `APIView` subclasses, default introspection is essentially
171+
limited to the URL kwarg path parameters. For `GenericAPIView`
172+
subclasses, which includes all the provided class based views, `AutoSchema` will
173+
attempt to introspect serialiser, pagination and filter fields, as well as
174+
provide richer path field descriptions. (The key hooks here are the relevant
175+
`GenericAPIView` attributes and methods: `get_serializer`, `pagination_class`,
176+
`filter_backends` and so on.)
177+
178+
---
179+
180+
In order to customise the operation generation, you should provide an `AutoSchema` subclass, overriding `get_operation()` as you need:
181+
182+
183+
from rest_framework.views import APIView
184+
from rest_framework.schemas.openapi import AutoSchema
185+
186+
class CustomSchema(AutoSchema):
187+
def get_link(...):
188+
# Implement custom introspection here (or in other sub-methods)
189+
190+
class CustomView(APIView):
191+
"""APIView subclass with custom schema introspection."""
192+
schema = CustomSchema()
193+
194+
This provides complete control over view introspection.
195+
196+
You may disable schema generation for a view by setting `schema` to `None`:
197+
198+
class CustomView(APIView):
199+
...
200+
schema = None # Will not appear in schema
201+
202+
This also applies to extra actions for `ViewSet`s:
203+
204+
class CustomViewSet(viewsets.ModelViewSet):
205+
206+
@action(detail=True, schema=None)
207+
def extra_action(self, request, pk=None):
208+
...
209+
210+
If you wish to provide a base `AutoSchema` subclass to be used throughout your
211+
project you may adjust `settings.DEFAULT_SCHEMA_CLASS` appropriately.
212+
213+
[openapi]: https://github.com/OAI/OpenAPI-Specification
214+
[openapi-specification-extensions]: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#specification-extensions
215+
[openapi-operation]: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#operationObject

docs/topics/documenting-your-api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,9 @@ To implement a hypermedia API you'll need to decide on an appropriate media type
266266
[image-django-rest-swagger]: ../img/django-rest-swagger.png
267267
[image-apiary]: ../img/apiary.png
268268
[image-self-describing-api]: ../img/self-describing.png
269-
[schemas-examples]: ../api-guide/schemas/#examples
270269
[metadata-docs]: ../api-guide/metadata/
271270

271+
[schemas-examples]: ../api-guide/schemas/#examples
272272
[swagger-ui]: https://swagger.io/tools/swagger-ui/
273273
[redoc]: https://github.com/Rebilly/ReDoc
274274

0 commit comments

Comments
 (0)