@@ -10,7 +10,14 @@ API schemas are a useful tool that allow for a range of use cases, including
10
10
generating reference documentation, or driving dynamic client libraries that
11
11
can interact with your API.
12
12
13
- ## Representing schemas internally
13
+ ## Install Core API
14
+
15
+ You'll need to install the ` coreapi ` package in order to add schema support
16
+ for REST framework.
17
+
18
+ pip install coreapi
19
+
20
+ ## Internal schema representation
14
21
15
22
REST framework uses [ Core API] [ coreapi ] in order to model schema information in
16
23
a format-independent representation. This information can then be rendered
@@ -68,9 +75,34 @@ has to be rendered into the actual bytes that are used in the response.
68
75
REST framework includes a renderer class for handling this media type, which
69
76
is available as ` renderers.CoreJSONRenderer ` .
70
77
78
+ ### Alternate schema formats
79
+
71
80
Other schema formats such as [ Open API] [ open-api ] ("Swagger"),
72
- [ JSON HyperSchema] [ json-hyperschema ] , or [ API Blueprint] [ api-blueprint ] can
73
- also be supported by implementing a custom renderer class.
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'
99
+
100
+ def render(self, data, media_type=None, renderer_context=None):
101
+ codec = OpenAPICodec()
102
+ return codec.dump(data)
103
+
104
+
105
+
74
106
75
107
## Schemas vs Hypermedia
76
108
@@ -89,18 +121,121 @@ document, detailing both the current state and the available interactions.
89
121
Further information and support on building Hypermedia APIs with REST framework
90
122
is planned for a future version.
91
123
124
+
92
125
---
93
126
94
- # Adding a schema
127
+ # Creating a schema
95
128
96
- You'll need to install the ` coreapi ` package in order to add schema support
97
- for REST framework .
129
+ REST framework includes functionality for auto-generating a schema,
130
+ or allows you to specify one explicitly .
98
131
99
- pip install coreapi
132
+ ## Manual Schema Specification
100
133
101
- REST framework includes functionality for auto-generating a schema,
102
- or allows you to specify one explicitly. There are a few different ways to
103
- add a schema to your API, depending on exactly what you need.
134
+ To manually specify a schema you create a Core API ` Document ` , similar to the
135
+ example above.
136
+
137
+ schema = coreapi.Document(
138
+ title='Flight Search API',
139
+ content={
140
+ ...
141
+ }
142
+ )
143
+
144
+
145
+ ## Automatic Schema Generation
146
+
147
+ Automatic schema generation is provided by the ` SchemaGenerator ` class.
148
+
149
+ ` SchemaGenerator ` processes a list of routed URL pattterns and compiles the
150
+ appropriately structured Core API Document.
151
+
152
+ Basic usage is just to provide the title for your schema and call
153
+ ` get_schema() ` :
154
+
155
+ generator = schemas.SchemaGenerator(title='Flight Search API')
156
+ schema = generator.get_schema()
157
+
158
+ ### Per-View Schema Customisation
159
+
160
+ By default, view introspection is performed by an ` AutoSchema ` instance
161
+ accessible via the ` schema ` attribute on ` APIView ` . This provides the
162
+ appropriate Core API ` Link ` object for the view, request method and path:
163
+
164
+ auto_schema = view.schema
165
+ coreapi_link = auto_schema.get_link(...)
166
+
167
+ (In compiling the schema, ` SchemaGenerator ` calls ` view.schema.get_link() ` for
168
+ each view, allowed method and path.)
169
+
170
+ To customise the ` Link ` generation you may:
171
+
172
+ * Instantiate ` AutoSchema ` on your view with the ` manual_fields ` kwarg:
173
+
174
+ from rest_framework.views import APIView
175
+ from rest_framework.schemas import AutoSchema
176
+
177
+ class CustomView(APIView):
178
+ ...
179
+ schema = AutoSchema(
180
+ manual_fields=[
181
+ coreapi.Field("extra_field", ...),
182
+ ]
183
+ )
184
+
185
+ This allows extension for the most common case without subclassing.
186
+
187
+ * Provide an ` AutoSchema ` subclass with more complex customisation:
188
+
189
+ from rest_framework.views import APIView
190
+ from rest_framework.schemas import AutoSchema
191
+
192
+ class CustomSchema(AutoSchema):
193
+ def get_link(...):
194
+ # Implemet custom introspection here (or in other sub-methods)
195
+
196
+ class CustomView(APIView):
197
+ ...
198
+ schema = CustomSchema()
199
+
200
+ This provides complete control over view introspection.
201
+
202
+ * Instantiate ` ManualSchema ` on your view, providing the Core API ` Fields ` for
203
+ the view explicitly:
204
+
205
+ from rest_framework.views import APIView
206
+ from rest_framework.schemas import ManualSchema
207
+
208
+ class CustomView(APIView):
209
+ ...
210
+ schema = ManualSchema(fields=[
211
+ coreapi.Field(
212
+ "first_field",
213
+ required=True,
214
+ location="path",
215
+ schema=coreschema.String()
216
+ ),
217
+ coreapi.Field(
218
+ "second_field",
219
+ required=True,
220
+ location="path",
221
+ schema=coreschema.String()
222
+ ),
223
+ ])
224
+
225
+ This allows manually specifying the schema for some views whilst maintaining
226
+ automatic generation elsewhere.
227
+
228
+ ---
229
+
230
+ ** Note** : For full details on ` SchemaGenerator ` plus the ` AutoSchema ` and
231
+ ` ManualSchema ` descriptors see the [ API Reference below] ( #api-reference ) .
232
+
233
+ ---
234
+
235
+ # Adding a schema view
236
+
237
+ There are a few different ways to add a schema view to your API, depending on
238
+ exactly what you need.
104
239
105
240
## The get_schema_view shortcut
106
241
@@ -342,38 +477,12 @@ A generic viewset with sections in the class docstring, using multi-line style.
342
477
343
478
---
344
479
345
- # Alternate schema formats
346
-
347
- In order to support an alternate schema format, you need to implement a custom renderer
348
- class that handles converting a ` Document ` instance into a bytestring representation.
349
-
350
- If there is a Core API codec package that supports encoding into the format you
351
- want to use then implementing the renderer class can be done by using the codec.
352
-
353
- ## Example
354
-
355
- For example, the ` openapi_codec ` package provides support for encoding or decoding
356
- to the Open API ("Swagger") format:
357
-
358
- from rest_framework import renderers
359
- from openapi_codec import OpenAPICodec
360
-
361
- class SwaggerRenderer(renderers.BaseRenderer):
362
- media_type = 'application/openapi+json'
363
- format = 'swagger'
364
-
365
- def render(self, data, media_type=None, renderer_context=None):
366
- codec = OpenAPICodec()
367
- return codec.dump(data)
368
-
369
- ---
370
-
371
480
# API Reference
372
481
373
482
## SchemaGenerator
374
483
375
- A class that deals with introspecting your API views, which can be used to
376
- generate a schema .
484
+ A class that walks a list of routed URL patterns, requests the schema for each view,
485
+ and collates the resulting CoreAPI Document .
377
486
378
487
Typically you'll instantiate ` SchemaGenerator ` with a single argument, like so:
379
488
@@ -406,39 +515,108 @@ Return a nested dictionary containing all the links that should be included in t
406
515
This is a good point to override if you want to modify the resulting structure of the generated schema,
407
516
as you can build a new dictionary with a different layout.
408
517
409
- ### get_link(self, path, method, view)
518
+
519
+ ## AutoSchema
520
+
521
+ A class that deals with introspection of individual views for schema generation.
522
+
523
+ ` AutoSchema ` is attached to ` APIView ` via the ` schema ` attribute.
524
+
525
+ The ` AutoSchema ` constructor takes a single keyword argument ` manual_fields ` .
526
+
527
+ ** ` manual_fields ` ** : a ` list ` of ` coreapi.Field ` instances that will be added to
528
+ the generated fields. Generated fields with a matching ` name ` will be overwritten.
529
+
530
+ class CustomView(APIView):
531
+ schema = AutoSchema(manual_fields=[
532
+ coreapi.Field(
533
+ "my_extra_field",
534
+ required=True,
535
+ location="path",
536
+ schema=coreschema.String()
537
+ ),
538
+ ])
539
+
540
+ For more advanced customisation subclass ` AutoSchema ` to customise schema generation.
541
+
542
+ class CustomViewSchema(AutoSchema):
543
+ """
544
+ Overrides `get_link()` to provide Custom Behavior X
545
+ """
546
+
547
+ def get_link(self, path, method, base_url):
548
+ link = super().get_link(path, method, base_url)
549
+ # Do something to customize link here...
550
+ return link
551
+
552
+ class MyView(APIView):
553
+ schema = CustomViewSchema()
554
+
555
+ The following methods are available to override.
556
+
557
+ ### get_link(self, path, method, base_url)
410
558
411
559
Returns a ` coreapi.Link ` instance corresponding to the given view.
412
560
561
+ This is the main entry point.
413
562
You can override this if you need to provide custom behaviors for particular views.
414
563
415
- ### get_description(self, path, method, view )
564
+ ### get_description(self, path, method)
416
565
417
566
Returns a string to use as the link description. By default this is based on the
418
567
view docstring as described in the "Schemas as Documentation" section above.
419
568
420
- ### get_encoding(self, path, method, view )
569
+ ### get_encoding(self, path, method)
421
570
422
571
Returns a string to indicate the encoding for any request body, when interacting
423
572
with the given view. Eg. ` 'application/json' ` . May return a blank string for views
424
573
that do not expect a request body.
425
574
426
- ### get_path_fields(self, path, method, view ):
575
+ ### get_path_fields(self, path, method):
427
576
428
577
Return a list of ` coreapi.Link() ` instances. One for each path parameter in the URL.
429
578
430
- ### get_serializer_fields(self, path, method, view )
579
+ ### get_serializer_fields(self, path, method)
431
580
432
581
Return a list of ` coreapi.Link() ` instances. One for each field in the serializer class used by the view.
433
582
434
- ### get_pagination_fields(self, path, method, view
583
+ ### get_pagination_fields(self, path, method)
435
584
436
585
Return a list of ` coreapi.Link() ` instances, as returned by the ` get_schema_fields() ` method on any pagination class used by the view.
437
586
438
- ### get_filter_fields(self, path, method, view )
587
+ ### get_filter_fields(self, path, method)
439
588
440
589
Return a list of ` coreapi.Link() ` instances, as returned by the ` get_schema_fields() ` method of any filter classes used by the view.
441
590
591
+
592
+ ## ManualSchema
593
+
594
+ Allows manually providing a list of ` coreapi.Field ` instances for the schema,
595
+ plus an optional description.
596
+
597
+ class MyView(APIView):
598
+ schema = ManualSchema(fields=[
599
+ coreapi.Field(
600
+ "first_field",
601
+ required=True,
602
+ location="path",
603
+ schema=coreschema.String()
604
+ ),
605
+ coreapi.Field(
606
+ "second_field",
607
+ required=True,
608
+ location="path",
609
+ schema=coreschema.String()
610
+ ),
611
+ ]
612
+ )
613
+
614
+ The ` ManualSchema ` constructor takes two arguments:
615
+
616
+ ** ` fields ` ** : A list of ` coreapi.Field ` instances. Required.
617
+
618
+ ** ` description ` ** : A string description. Optional.
619
+
442
620
---
443
621
444
622
## Core API
0 commit comments