Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ca0319d

Browse files
committed
initial implementation of OAS 3.0 generateschema
1 parent b14d8ab commit ca0319d

File tree

19 files changed

+2168
-2
lines changed

19 files changed

+2168
-2
lines changed

‎AUTHORS‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Jason Housley <housleyjk@gmail.com>
1414
Jerel Unruh <mail@unruhdesigns.com>
1515
Jonathan Senecal <contact@jonathansenecal.com>
1616
Joseba Mendivil <git@jma.email>
17+
Kieran Evans <keyz182@gmail.com>
1718
Léo S. <leo@naeka.fr>
1819
Luc Cary <luc.cary@gmail.com>
1920
Matt Layman <https://www.mattlayman.com>

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ any parts of the framework not mentioned in the documentation should generally b
1313
### Added
1414

1515
* Added support for serializing nested serializers as attribute json value introducing setting `JSON_API_SERIALIZE_NESTED_SERIALIZERS_AS_ATTRIBUTE`
16+
* Add support openapi schema and for `generateschema` management command.
1617

1718
### Fixed
1819

‎docs/usage.md‎

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
1+
`
22
# Usage
33

44
The DJA package implements a custom renderer, parser, exception handler, query filter backends, and
@@ -32,6 +32,7 @@ REST_FRAMEWORK = {
3232
'rest_framework.renderers.BrowsableAPIRenderer'
3333
),
3434
'DEFAULT_METADATA_CLASS': 'rest_framework_json_api.metadata.JSONAPIMetadata',
35+
'DEFAULT_SCHEMA_CLASS': 'rest_framework_json_api.schemas.openapi.AutoSchema',
3536
'DEFAULT_FILTER_BACKENDS': (
3637
'rest_framework_json_api.filters.QueryParameterValidationFilter',
3738
'rest_framework_json_api.filters.OrderingFilter',
@@ -937,3 +938,117 @@ The `prefetch_related` case will issue 4 queries, but they will be small and fas
937938
### Relationships
938939
### Errors
939940
-->
941+
942+
## Generating an OpenAPI Specification (OAS) 3.0 schema document
943+
944+
DRF 3.10 added a new management command: `generateschema` which can generate an
945+
[OAS 3.0 schema](https://www.openapis.org/) as a YAML or JSON file.
946+
947+
### Settings needed
948+
949+
In order to produce an OAS schema that properly represents the JSON:API structure,
950+
DJA has this same command as an override of DRF's. In order to make sure the DJA
951+
version of the command is used, you must add DJA **ahead of** DRF in the
952+
`INSTALLED_APPS` settings as in this example:
953+
```python
954+
INSTALLED_APPS = [
955+
'django.contrib.contenttypes',
956+
'django.contrib.staticfiles',
957+
'django.contrib.sites',
958+
'django.contrib.sessions',
959+
'django.contrib.auth',
960+
'rest_framework_json_api',
961+
'rest_framework',
962+
'polymorphic',
963+
'example',
964+
'debug_toolbar',
965+
'django_filters',
966+
]
967+
```
968+
969+
You'll also need to make sure you are using the DJA AutoSchema class, either as the default schema class or
970+
explicitly as a view's `schema`:
971+
972+
### Default schema class
973+
974+
```python
975+
REST_FRAMEWORK = {
976+
# ...
977+
'DEFAULT_SCHEMA_CLASS': 'rest_framework_json_api.schemas.openapi.AutoSchema',
978+
}
979+
```
980+
981+
### View-based
982+
983+
You can explicitly use DJA's AutoSchema in your view definition, optionally including an OAS schema document
984+
initializer:
985+
986+
```python
987+
from rest_framework_json_api.schemas.openapi import AutoSchema
988+
989+
openapi_schema = {
990+
'info': {
991+
'version': '1.0',
992+
'title': 'my demo API',
993+
'description': 'A demonstration of [OAS 3.0](https://www.openapis.org) AutoSchema',
994+
'contact': {
995+
'name': 'my name'
996+
},
997+
'license': {
998+
'name': 'BSD 2 clause',
999+
'url': 'https://github.com/django-json-api/django-rest-framework-json-api/blob/master/LICENSE',
1000+
}
1001+
},
1002+
'servers': [
1003+
{'url': 'https://localhost/v1', 'description': 'local docker'},
1004+
{'url': 'http://localhost:8000/v1', 'description': 'local dev'},
1005+
{'url': 'https://api.example.com/v1', 'description': 'demo server'},
1006+
{'url': '{serverURL}', 'description': 'provide your server URL',
1007+
'variables': {'serverURL': {'default': 'http://localhost:8000/v1'}}}
1008+
]
1009+
}
1010+
1011+
1012+
class MyViewSet(ModelViewSet):
1013+
schema = AutoSchema(openapi_schema=openapi_schema)
1014+
```
1015+
1016+
### Get Schema in View
1017+
1018+
Add the following to `urls.py`, to expose the schema at `/openapi`. This can be consumed by (Swagger UI)[https://swagger.io/tools/swagger-ui/] or other tools.
1019+
```python
1020+
from rest_framework.schemas import get_schema_view
1021+
from rest_framework_json_api.schemas.openapi import SchemaGenerator
1022+
1023+
...
1024+
1025+
urlpatterns = [
1026+
path('openapi', get_schema_view(
1027+
title="Example API",
1028+
description="API for all things ...",
1029+
version="1.0.0",
1030+
generator_class=SchemaGenerator
1031+
), name='openapi-schema'),
1032+
...
1033+
]
1034+
```
1035+
### Get Schema on Command Line
1036+
To generate an OAS schema document, use something like:
1037+
1038+
```text
1039+
$ django-admin generateschema --settings=example.settings >myschema.yaml
1040+
```
1041+
1042+
You can then use any number of OAS tools such as
1043+
[swagger-ui-watcher](https://www.npmjs.com/package/swagger-ui-watcher)
1044+
to render the schema:
1045+
```text
1046+
$ swagger-ui-watcher myschema.yaml
1047+
```
1048+
1049+
Note: Swagger-ui-watcher will complain that "DELETE operations cannot have a requestBody"
1050+
but it will still work. This
1051+
[error](https://github.com/OAI/OpenAPI-Specification/pull/1937)
1052+
in the OAS specification is expected to be fixed soon.
1053+
([swagger-ui](https://www.npmjs.com/package/swagger-ui) will work silently.)
1054+

‎example/settings/dev.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
'django.contrib.sites',
2222
'django.contrib.sessions',
2323
'django.contrib.auth',
24+
'rest_framework_json_api',
2425
'rest_framework',
2526
'polymorphic',
2627
'example',
@@ -88,6 +89,7 @@
8889
'rest_framework.renderers.BrowsableAPIRenderer',
8990
),
9091
'DEFAULT_METADATA_CLASS': 'rest_framework_json_api.metadata.JSONAPIMetadata',
92+
'DEFAULT_SCHEMA_CLASS': 'rest_framework_json_api.schemas.openapi.AutoSchema',
9193
'DEFAULT_FILTER_BACKENDS': (
9294
'rest_framework_json_api.filters.OrderingFilter',
9395
'rest_framework_json_api.django_filters.DjangoFilterBackend',

‎example/templates/swagger-ui.html‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Swagger</title>
5+
<meta charset="utf-8"/>
6+
<meta name="viewport" content="width=device-width, initial-scale=1">
7+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.23.11/swagger-ui.css" integrity="sha256-O3WBPOmqAcumrGlHJtGp6KtuKA4S9sbEu3NCSbacxZ8=" crossorigin="anonymous" />
8+
</head>
9+
<body>
10+
<div id="swagger-ui"></div>
11+
12+
<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.23.11/swagger-ui-standalone-preset.js" integrity="sha256-AGfcF/HKnhqGTZNL+pNGJ+yemAzr2tuvbP69pYbn+GU=" crossorigin="anonymous"></script>
13+
<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.23.11/swagger-ui-bundle.js" integrity="sha256-wmWvmMbIQjnhA5qXYJAw60JjO3/zvM2T/BMnbdBD26w=" crossorigin="anonymous"></script>
14+
<script>
15+
const ui = SwaggerUIBundle({
16+
url: "{% url schema_url %}",
17+
dom_id: '#swagger-ui',
18+
deepLinking: true,
19+
presets: [
20+
SwaggerUIBundle.presets.apis,
21+
SwaggerUIStandalonePreset
22+
],
23+
plugins: [
24+
SwaggerUIBundle.plugins.DownloadUrl
25+
],
26+
layout: "StandaloneLayout"
27+
})
28+
</script>
29+
</body>
30+
</html>

‎example/tests/snapshots/__init__.py‎

Whitespace-only changes.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /