Skip to content
This repository has been archived by the owner on Jun 6, 2024. It is now read-only.

deserialization of responses from flask-rest-jsonapi not working #294

Open
turekaj opened this issue Feb 28, 2020 · 4 comments
Open

deserialization of responses from flask-rest-jsonapi not working #294

turekaj opened this issue Feb 28, 2020 · 4 comments

Comments

@turekaj
Copy link

turekaj commented Feb 28, 2020

I currently use flask-rest-jsonapi (https://flask-rest-jsonapi.readthedocs.io/en/latest/) to implement an API. I have defined my schemas and relationshipsusing marshmallow_jsonapi.flask, and the schemas live in another project.

I attempted to create a client which would import the schemas, and utilize the requests library to make http requests to my backend.

MySchema().loads(response.json()) gives back "unknown fields" for things that are not listed in the "attributes" of the jsonapi response. The json response from flask-rest-jsonapi looks correct, and response.json() turns that json into a dict (which is passed to loads)

Am I do something something wrong here?

@turekaj turekaj changed the title deserialization of responds from flask-rest-jsonapi not working deserialization of responses from flask-rest-jsonapi not working Feb 28, 2020
@multimeric
Copy link

From memory, flask-rest-jsonapi adds some metadata, like the jsonapi version, which will cause you to have trouble if you load them via marshmallow-jsonapi.

My hack to solve this for my API is simply deleting the metadata and jsonapi keys: https://github.com/ewels/MegaQC/blob/130cafdb1f74b042385d0645a7acf11e8129f8d7/tests/api/test_api.py#L202-L204

@turekaj
Copy link
Author

turekaj commented Mar 2, 2020

The error is actually a validation error of my "attributes". Note, I have replaced the actual names of my fields with field_name_1, etc below.

JSON response after deleting ret['meta'] and ret['jsonapi']
{'data': [{'attributes': {
// i see all the fields that were "unknown in the validation here. Some are also here that do not cause validation to puke"
....

marshmallow.exceptions.ValidationError: {0: {'field_name_1': ['Unknown field.'], 'field_name_2': ['Unknown field.'], 'field_name_3': ['Unknown field.'], 'field_name_4': ['Unknown field.'], 'field_name_5': ['Unknown field.'], 'field_name_6': ['Unknown field.']}}

Client:
` r = self._session.get(self._root_url + 'redacted', timeout=self._timeouts, params=payload)
r.raise_for_status()
ret = r.json()
del ret['meta']
del ret['jsonapi']

    data = schemas.RedactedSchema(many=True).load(ret)
    return dat`

Schema:
`
class RedactedSchema(Schema):
class Meta:
ordered = True
type_ = 'redacted'
self_view = 'redacted_detail'
self_view_kwargs = {'id':''}
self_view_many = '_list'

field_name_2 = fields.Integer(dump_only=True, attributes='id')
field_name_4 = fields.UUID(dump_only=True, attributes='uuid')
field_name_d = fields.String()
field_name_c = fields.String(required=True)
field_name_b = fields.String(required=False)
field_name_a = fields.String(required=False)
field_name_9 = fields.String(required=True)
field_name_8 = fields.String(required=True)
field_name_7 = fields.String(allow_none=True)

field_name_3 = fields.String(dump_only=True)
field_name_5 = fields.Integer(dump_only=True)
field_name_1 = fields.DateTime(dump_only=True)
field_name_6= fields.DateTime(dump_only=True)`

@turekaj
Copy link
Author

turekaj commented Mar 2, 2020

I think I see the issue.

I have fields set as dump_only so that they are really read-only fields. However, I want to share the same schema between my client and server code.

  1. do GET request from server. Schema is populated from DB, and then serialized out to jsonapi
  2. client gets response back, attempts to de-serialize response into schema, but schema has dump_only=True for fields that were returned and validation fails.

The client only wants read-only access to those fields.

@turekaj
Copy link
Author

turekaj commented Mar 2, 2020

Replacing dump_only=True with the following 3 parameters gets close to what I want.
required=False, missing=None, allow_none=True,

I believe now the real solution is define two schemas, one for server, one for client, that are identical, except for the field parameters.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants