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

Add support for parsing arbitrary JSON data #1079

aseidma started this conversation in Ideas
Discussion options

Currently rest_framework_json_api.parsers.JSONParser only accepts stream-like objects as an input, intended for parsing incoming requests. This is fine and intended behavior for many use-cases.

However, there are edge cases where json:api's specification is limited, e.g. when uploading files along with JSON data. This has been an open discussion for years (see json-api/json-api#246).

One (seemingly widely used) way to achieve this behavior is by sending the data as multipart/form-data and specifying a data field with the JSON data as well as an additional field for files.
This is then handled with a custom parser, inheriting functionality from rest_framework.parsers.MultiPartParser. This works in a similar fashion as the parse method in JSONParser, first running the request data through the parent parser and modifying it to fit the desired schema afterwards.

The issue is that once you received the JSON data from MultiPartParser, there is no function on DRFJA to format that payload. You have to overwrite/copy-paste into your own method to access the parsing functionality after the inital rest_framework.parsers.JSONParser call.

Showing some code might explain it better:

# rest_framework_json_api/parsers.py#JSONParser
def parse(self, stream, media_type=None, parser_context=None):
 # We do not need this
 result = super().parse(
 stream, media_type=media_type, parser_context=parser_context
 )
 
 # We need everything starting from here as a separate method
 # ... some parsing to specification happening here
 return parsed_data

This could be achieved by adding an extra method like parse_json, both making it public and using it from within the existing parser method. Building custom parsers for DRFJA would be made a little easier this way. I would be happy to provide the PR.

Any thoughts on this?

Here is an example of what a custom parser using this could look like:

class MultiPartJsonParser(parsers.MultiPartParser):
 def parse(self, stream, media_type=None, parser_context=None):
 result = super().parse(
 stream,
 media_type=media_type,
 parser_context=parser_context
 )
 data = json.loads(result.data['data'])
 # Use parse_json to parse simple json rather than a request
 japi_data = parsers.JSONParser.parse_json(data, media_type, parser_context)
 return parsers.DataAndFiles(japi_data, result.files)
You must be logged in to vote

Replies: 1 comment

Comment options

Thanks for bringing up this discussion.

I would be skeptical to include a MultiPartParser in DJA as it is not standardized (yet) how it supposed to work. I am very supportive though to make the public API of DJA as easy extensible as possible so not standardized features can be experimented with in 3rdParty libraries.

Therefore, feel free to open a PR. I would call the method rather parse_data which makes more sense in the JSON:API spec context.

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Ideas
Labels
None yet
2 participants

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