0
# Renderers and Parsers
1
2
JSON:API renderers convert Django REST framework responses to JSON:API format, while parsers handle incoming JSON:API requests. These components ensure proper resource object structure, relationship handling, meta information, and error formatting.
3
4
## Capabilities
5
6
### JSONRenderer
7
8
Main JSON:API renderer that transforms Django REST framework responses into JSON:API compliant format.
9
10
```python { .api }
11
class JSONRenderer(renderers.JSONRenderer):
12
"""
13
JSON:API compliant renderer with media type application/vnd.api+json.
14
15
Transforms Django REST framework responses into JSON:API format with:
16
- Resource objects with type, id, attributes, and relationships
17
- Top-level data, meta, and links sections
18
- Proper error formatting
19
- Include parameter support for compound documents
20
"""
21
22
media_type = "application/vnd.api+json"
23
format = "vnd.api+json"
24
25
@classmethod
26
def extract_attributes(cls, fields, resource):
27
"""
28
Extract attributes from resource data for JSON:API resource object.
29
30
Args:
31
fields: Serializer fields dict
32
resource: Resource data dict
33
34
Returns:
35
dict: Attributes dict with formatted field names
36
"""
37
38
@classmethod
39
def extract_relationships(cls, fields, resource, resource_instance):
40
"""
41
Extract relationships from resource data for JSON:API resource object.
42
43
Args:
44
fields: Serializer fields dict
45
resource: Resource data dict
46
resource_instance: Django model instance
47
48
Returns:
49
dict: Relationships dict with data and links
50
"""
51
52
def render(self, data, accepted_media_type=None, renderer_context=None):
53
"""
54
Render data as JSON:API response.
55
56
Args:
57
data: Data to render
58
accepted_media_type: Accepted media type
59
renderer_context: Request context
60
61
Returns:
62
bytes: JSON:API formatted response
63
"""
64
```
65
66
Usage example:
67
68
```python
69
# settings.py
70
REST_FRAMEWORK = {
71
'DEFAULT_RENDERER_CLASSES': [
72
'rest_framework_json_api.renderers.JSONRenderer',
73
],
74
}
75
76
# Transforms this Django REST framework response:
77
# {"id": 1, "title": "Article", "author": 5}
78
79
# Into this JSON:API response:
80
# {
81
# "data": {
82
# "type": "articles",
83
# "id": "1",
84
# "attributes": {
85
# "title": "Article"
86
# },
87
# "relationships": {
88
# "author": {
89
# "data": {"type": "authors", "id": "5"}
90
# }
91
# }
92
# }
93
# }
94
```
95
96
### JSONParser
97
98
JSON:API parser that converts incoming JSON:API requests into Django REST framework format.
99
100
```python { .api }
101
class JSONParser(parsers.JSONParser):
102
"""
103
JSON:API compliant parser with media type application/vnd.api+json.
104
105
Parses JSON:API requests and extracts:
106
- Attributes from resource objects
107
- Relationships as resource identifier objects
108
- Meta information
109
"""
110
111
media_type = "application/vnd.api+json"
112
renderer_class = JSONRenderer
113
114
@staticmethod
115
def parse_attributes(data):
116
"""
117
Parse attributes from JSON:API resource object.
118
119
Args:
120
data: JSON:API resource object data
121
122
Returns:
123
dict: Attributes with field names converted to Django format
124
"""
125
126
@staticmethod
127
def parse_relationships(data):
128
"""
129
Parse relationships from JSON:API resource object.
130
131
Args:
132
data: JSON:API resource object data
133
134
Returns:
135
dict: Relationships as resource identifier objects
136
"""
137
138
@staticmethod
139
def parse_metadata(result):
140
"""
141
Parse meta section from JSON:API request.
142
143
Args:
144
result: Full JSON:API request data
145
146
Returns:
147
dict: Meta information with _meta key
148
"""
149
150
def parse_data(self, result, parser_context):
151
"""
152
Parse JSON:API request data into Django REST framework format.
153
154
Args:
155
result: Parsed JSON data
156
parser_context: Parser context with view information
157
158
Returns:
159
dict: Data in Django REST framework format
160
161
Raises:
162
ParseError: If request doesn't contain primary data or is malformed
163
"""
164
```
165
166
Usage example:
167
168
```python
169
# settings.py
170
REST_FRAMEWORK = {
171
'DEFAULT_PARSER_CLASSES': [
172
'rest_framework_json_api.parsers.JSONParser',
173
],
174
}
175
176
# Parses this JSON:API request:
177
# {
178
# "data": {
179
# "type": "articles",
180
# "attributes": {
181
# "title": "New Article",
182
# "content": "Article content"
183
# },
184
# "relationships": {
185
# "author": {
186
# "data": {"type": "authors", "id": "5"}
187
# }
188
# }
189
# }
190
# }
191
192
# Into this Django REST framework format:
193
# {
194
# "title": "New Article",
195
# "content": "Article content",
196
# "author": {"type": "authors", "id": "5"}
197
# }
198
```
199
200
## Response Structure
201
202
The JSONRenderer creates responses with this structure:
203
204
### Single Resource
205
206
```python
207
{
208
"data": {
209
"type": "resource-type",
210
"id": "123",
211
"attributes": {
212
"field-name": "value"
213
},
214
"relationships": {
215
"related-field": {
216
"data": {"type": "related-type", "id": "456"}
217
}
218
},
219
"links": {
220
"self": "/api/resource-type/123"
221
}
222
},
223
"meta": {
224
"key": "value"
225
}
226
}
227
```
228
229
### Resource Collection
230
231
```python
232
{
233
"data": [
234
{
235
"type": "resource-type",
236
"id": "123",
237
"attributes": {...},
238
"relationships": {...}
239
}
240
],
241
"meta": {
242
"pagination": {
243
"page": 1,
244
"pages": 10,
245
"count": 100
246
}
247
},
248
"links": {
249
"first": "/api/resource-type?page=1",
250
"next": "/api/resource-type?page=2",
251
"last": "/api/resource-type?page=10"
252
}
253
}
254
```
255
256
### Error Response
257
258
```python
259
{
260
"errors": [
261
{
262
"status": "400",
263
"detail": "This field is required.",
264
"source": {
265
"pointer": "/data/attributes/title"
266
}
267
}
268
]
269
}
270
```
271
272
## Field Name Formatting
273
274
Both renderer and parser respect field name formatting settings:
275
276
```python
277
# settings.py
278
JSON_API_FORMAT_FIELD_NAMES = True
279
280
# Django field: created_at
281
# JSON:API attribute: "created-at"
282
283
# Parser automatically converts back:
284
# JSON:API "created-at" -> Django "created_at"
285
```
286
287
## Include Parameter Support
288
289
The renderer supports compound documents via the include parameter:
290
291
```python
292
# Request: GET /articles/1?include=author,comments.user
293
# Response includes related resources in "included" section:
294
{
295
"data": {...},
296
"included": [
297
{
298
"type": "authors",
299
"id": "5",
300
"attributes": {...}
301
},
302
{
303
"type": "comments",
304
"id": "10",
305
"attributes": {...},
306
"relationships": {
307
"user": {"data": {"type": "users", "id": "3"}}
308
}
309
}
310
]
311
}
312
```
313
314
## Relationship View Support
315
316
The parser handles relationship endpoint requests:
317
318
```python
319
# POST /articles/1/relationships/author
320
# {
321
# "data": {"type": "authors", "id": "6"}
322
# }
323
324
# Parser extracts relationship data for relationship views
325
```
326
327
## Types
328
329
```python { .api }
330
from rest_framework_json_api.renderers import JSONRenderer
331
from rest_framework_json_api.parsers import JSONParser
332
333
# Base classes from Django REST framework
334
from rest_framework.renderers import JSONRenderer as DRFJSONRenderer
335
from rest_framework.parsers import JSONParser as DRFJSONParser
336
```