-
Notifications
You must be signed in to change notification settings - Fork 270
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question: How to get the schema for the currently active view and/or serializer (for validation)? #1349
Comments
Hi, not exactly sure what you try to do here. How is schema validation gonna help during your request processing?
its part of the mechanics DRF provides to make schema generation possible.
I wouldn't call it undocumented. its a private method, but in the context of spectacular means: "one of the methods not meant to be overridden as part of the regular workflow, but no real reasons why you can't with some caution"
You can try generating a schema outside of the generator but your mileage may vary. there a bunch of things that get initialized there and there are no official guarantees when used like this. It may work or not. It is likely possible to beat it into submission and making it work, but again you are on your own there. The metadata classes in DRF are messy and seldom used. I consider it a waste of time. I do not recommend running it solo out-of-context on a view or endpoint. I would, if necessary, generate the whole schema once, cache it, and then pick out the stuff you need on a case by case basis. |
Hi!
This is about validating incoming data, e.g. in POST or PUT requests. My approach here is that what is documented should also be validated and vice versa. I'd like the information to be as close to the implementation as possible, which is why I adapt model fields first, if possible (which sometimes is not possible with 11 years of production data which might require expensive migrations if I change the model, or for backward compatibility with old clients) then serializer fields and if necessary (!) I use In the latter case I would have to write python code to enforce the validation, which could become inconsistent with the documentation. So I'd prefer as little duplication as possible and using the generated schema for data validation would close that gap nicely for me. (Also because we already use jsonschema for data validation anyways. Some of our data structures are recursive, which was not possible to express with openapi 2 and drf-yasg at all.)
👍 🙏
Thanks for the explanation! I would not like to have my code break too often because the approach we use is unsupported.
You might be right here. We do have one client that uses the OPTIONS method because it was quicker for that particular purpose, but that lives in the same repository as the server, which makes it easy to coordinate releases here. Adapting the options method return value certainly is low priority for me.
That does sound broadly like a feasible plan. Would I call the view directly for all supported versions of my API? When I look at the It would look roughly like this: def _get_schema_response(self, request):
return Response(
data=self._get_schema_data(request)),
headers={"Content-Disposition": f'inline; filename="{self._get_filename(request, version)}"'}
)
def _get_schema_data(self, request):
# version specified as parameter to the view always takes precedence. after
# that we try to source version through the schema view's own versioning_class.
version = self.api_version or request.version or self._get_version_parameter(request)
generator = self.generator_class(urlconf=self.urlconf, api_version=version, patterns=self.patterns)
return generator.get_schema(request=request, public=self.serve_public) (Edit: Yikes, that won't work that way because I would need to construct request objects for version 1 and 2 of our API. I'm going to try that out. Thanks for the advice! |
Historically we've been validating some parts of our API with JSON Schema and the API was documented via drf-yasg which wasn't compatible. Now I'm finally migrating to drf-spectacular and with
OAS_VERSION=3.1.0
it's even fully compatible with JSON Schema.This raises the question how we could use this for validation as well.
I've figured out that when I'm e.g. inside the
.validate()
method of a serializer, I can useself.context['view'].schema._map_serializer(self, 'request')
to get the request schema which I could just plug into the validate method of a jsonschema validator.Problems I see:
I can't see any documentation for the
.schema
property of the django-rest-framework view. Apparently drf-spectacular uses that as well, though.The
_map_serializer
method is undocumented.The real workflow in drf-spectacular (from the schema view) uses a generator object and is a bit more involved, however it accounts for the post processing hooks etc. which my hacky attempt above doesn't, which might be a problem if we change validation information in those hooks.
I'd really appreciate a simple way to get at the correct and intended (by the developers) scheme for a view and/or serializer from inside its code. Another use-case for this would be a custom metadata class which adds a
schema
property to the returned object which contains the valid json schema.It's not unlikely I'm missing something relevant here so I'd appreciate assistance.
Are there other approaches for using the generated schema for validation?
Thanks in advance and best regards
The text was updated successfully, but these errors were encountered: