DEV Community

Cover image for Quick tip: posting to JSON:APIs
Matheus Cardoso
Matheus Cardoso

Posted on

Quick tip: posting to JSON:APIs

Se você chegou aqui e não fala/ler/escreve nativamente inglês ou não prefere ler neste idioma, esse mesmo artigo está escrito em português do Brasil aqui.

This is a quick tip to newcomers to JSON:APIs. If you think it's just JSON, think again. It's JSON and "some more" definitions. Here's some stuff that I didn't know, underestimating the specs, and cracked my head.

First, the Content-Type ain't application/json.. The correct type is application/vnd.api+json. Otherwise, the server will respond with 415 Unsupported Media Type.

Second, your payload to POST must contain data (called "primary data") and must have at least the following format:

{
  "data": {
    "type": "my final 'secret' was here",
    "attributes": <your_payload>
  }
}
Enter fullscreen mode Exit fullscreen mode

If you miss data you'll get the following error:

{
   "errors":[
      {
         "detail":"Received document does not contain primary data",
         "source":{
            "pointer":"/data"
         },
         "status":"400"
      }
   ]
}
Enter fullscreen mode Exit fullscreen mode

You just need to add data and put your payload into attributes. After that if you miss type or setting as None, because we're POSTING, you will get the following error (or something similar):

{
   "errors":[
      {
         "detail":"The resource object's type (None) is not the type that constitute the collection represented by the endpoint (<ENDPOINT_NAME>).",
         "source":{
            "pointer":"/data"
         },
         "status":"409"
      }
   ]
}
Enter fullscreen mode Exit fullscreen mode

And the above error was the one that took my energy and made me write down this post. It took me a while to figure out, despite of message, what was the error, however it can be different in other situation/framework/structure, I think. Here was my situation, using Django + DRF + JSON:API:

from rest_framework.decorators import api_view

@api_view(["POST"])
def my_api_post_endoint(request):
    ...
Enter fullscreen mode Exit fullscreen mode

Giving the above endpoint, using @api_view (and I'm being pretty specific cuz I didn't tested with ViewSets or other class based endpoints) I just had to set the whole payload's type as the same name of my endpoint. Like bellow:

{
   "data":{
      "type":"my_api_post_endoint",
      "attributes":"payload"
   }
}
Enter fullscreen mode Exit fullscreen mode

And..Done! The POST was passing and I could move on with my work.

History's moral? Read the damn specs before. 😅

Top comments (1)

Collapse
 
asif_iqbal profile image
Mohamed Asif Iqbal

thank you for this :)