I'm creating an API using Django REST Framework 3.12.0. This is the latest version released on the 13th of October 2020.
The 3.10 version (September 2019) introduced OpenAPI based schema generation instead of CoreAPI, which has been deprecated (see release notes here).
This change introduces regressions in schema auto-generation:
- Redundant Operation IDs (
operators create
becomesoperators createOperator
, see example below), - A "workaround" is required to get schema using
coreapi
cli command (see here), - Mandatory parameters defined in serializer are not extracted in schema generation, thus I cannot properly use the
coreapi
cli command.
The last point is the real problematic one.
I can easily switch from the OpenAPI to the (deprecated) CoreAPI AutoSchema class changing the url
parameter in get_schema_view
function and adding this in settings.py
:
REST_FRAMEWORK = {
# [...]
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
}
Example
Below is an example using both schema classes.
models.py
:
class Operator(models.Model):
code = models.IntegerField(unique=True, blank=False, null=False)
first_name = models.CharField(max_length=45, unique=False, blank=False, null=False)
last_name = models.CharField(max_length=45, unique=False, blank=False, null=False)
serializers.py
:
class OperatorSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Operator
fields = ['url', 'id', 'code', 'first_name', 'last_name']
views.py
:
class OperatorViewSet(viewsets.ModelViewSet):
queryset = Operator.objects.all()
serializer_class = OperatorSerializer
permission_classes = [permissions.IsAuthenticated]
Using Core API
# No workaround
coreapi get http://127.0.0.1:8000/api/openapi
# [...]
operators: {
list([page])
create(code, first_name, last_name)
read(id)
update(id, code, first_name, last_name)
partial_update(id, [code], [first_name], [last_name])
delete(id)
}
# [...]
# I can create an operator.
coreapi action operators create --param code=1234 --param first_name="John" --param last_name="Doe"
{
"url": "http://127.0.0.1:8000/api/operators/68/",
"id": 68,
"code": 1234,
"first_name": "John",
"last_name": "Doe"
}
Using Open API
# Needs a workaround
coreapi get http://127.0.0.1:8000/api/openapi/?format=openapi-json --format=openapi
# [...]
operators: {
listOperators([page])
createOperator()
retrieveOperator(id)
updateOperator(id)
partialUpdateOperator(id)
destroyOperator(id)
}
# [...]
# I cannot create an operator as parameter are unknown.
coreapi action operators createOperator --param code=1234 --param first_name="John" --param last_name="Doe"
Traceback (most recent call last):
# [...]
coreapi.exceptions.ParameterError: {'first_name': 'Unknown parameter.', 'code': 'Unknown parameter.', 'last_name': 'Unknown parameter.'}
How to have a CoreAPI-like schema generation using the new OpenAPI one?