-
-
Notifications
You must be signed in to change notification settings - Fork 171
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
working with webargs meta-location #548
Comments
I don't know your DB but generally it is better to have a unique constraint in the DB and catch the duplicated ID exception when writing. Unless you're in a transaction, it is dangerous to check first then write because another item could be created in between the check and the write (race condition). Did you really mean load_only? In my apps, the ID is dump_only. In your case, I suppose you want to dump it but not allow the user to pass it in the payload. I don't see an obvious solution to your issue. You'd need to do that check somewhere else, I guess. Or not do it at all (see above). |
I agree with you on the race condition and I do have a unique constraint in the DB. My question is not really about my use case though, it's about webargs meta-locations and their compatibility with openapi and thus the swagger interface. Endpoints using meta-locations simply aren't callable in the swagger interface. |
I agree exposing meta-locations is bad. Meta-locations mean data can be found in several locations. I don't see how this fits in standard OpenAPI. In fact, the rework in webargs 6 makes it closer to OpenAPI and makes meta-location an exception. |
Alright. Is there any other way to pass |
AFAIU, the problem here is that the schema contains a field (the ID field) that you don't want to expose in the json payload in the spec. You can change the mapping to make Unless you make that field dump_only but then your validation won't work. |
At this point, I'm going to change the way my endpoint works in order to have all the data I need in the body the request. Thanks for your help! I suggest mentioning meta-locations don't play well with openapi in the docs: https://webargs.readthedocs.io/en/latest/advanced.html#meta-locations. |
Not sure this fits in webargs docs as webargs is not "apispec-aware". I'd keep attr_id as path param and I wouldn't do that verification at schema validation. Well, in fact I wouldn't do that verification at all, as said above. Perhaps you could do it in a custom decorator to get all arguments. Anyway, I think it should work if you complete the mapping as said above. However, I'm surprised your schema load and validation work while the id field is dump_only. |
I understand your point about not doing the verification and leaving it to the database. |
I understand. What I do is catch DB error and use abort to return a consistent 422 error. I understand the leakage issue. Depending on the size of your app, you may want to just live with it (easy and fast) or add an abstraction layer to encapsulate DB operations. |
When catching database errors do you then try to mimic a standard 422 error with a message linking that error back to a field or do you just use |
No. Maybe I should. I don't feel the need to optimize this. It shouldn't happen in the first place. I mean an app must manage client errors. But optimize client error processing?
Up to you to use a simple string message or link to a field (or several fields if the error spans on several fields, like unique constraint on two fields). See marshmallow-code/flask-smorest#132 (comment). It can depend on how your client actually parses the error response. Error structuring is nice when debugging, on to help UI providing errors to client. But some errors might not fit in this structure. Catching database connection errors might not be necessary: ultimately, return a 500 might be enough from client perspective client. I include traceback in the logs. |
You must have really nice clients :)
I will definitely use this, thanks |
Yeah, or not client at all... My point in this example is that for the client, it does not matter that much if the error is a database server error, a network error, whatever. That's internal details. The server can't answer, it is a server error. |
I agree that the client should not be exposed to the underlying complexity of the database model, that is one of the reasons to use APIs. |
I think we agree. Ideally, a 500 is logged and perhaps triggers a notification to the maintainer somehow. And it may contain a message like "please tell the admin". Just saying the user shouldn't need to know it's a DB error or a network error since in any case he can't do anything about it. But yes, it may be slightly better in terms of communication to provide unneeded details so that the backend code doesn't appears as just a broken blob. |
In my api, in order to isolate validation code, I created a meta-location (following this example from the documentation https://webargs.readthedocs.io/en/latest/advanced.html#meta-locations):
And I'm using it as followed in my api:
Here's the schema:
And here's the generated openapi.json:
The swagger interface is unable to post data using this json.
My goal is to make openapi understand that
view_args_and_json
is supposed to be arequestBody
and thatattr_id
is not supposed to be part of the body because it is a load-only field.I've tried to add my meta-location to
__location_map__
(https://github.com/marshmallow-code/apispec/blob/dev/src/apispec/ext/marshmallow/openapi.py#L30) without success.The text was updated successfully, but these errors were encountered: