jsonapi-rb / jsonapi-rails

Rails gem for fast jsonapi-compliant APIs.
http://jsonapi-rb.org
MIT License
319 stars 63 forks source link

When a parameter is missing the error is returned without a source #93

Open JoeWoodward opened 6 years ago

JoeWoodward commented 6 years ago

Currently when my model validates a value that was completely excluded from the payload I get a response with empty pointers.

{
  "errors": [
    {
      "title": "Invalid user_id",
      "detail": "User can't be blank",
      "source": {}
    }
  ],
  "jsonapi": {
    "version": "1.0"
  }
}

In rails we know the source ahead of time. If it's not a query parameter then it must be a pointer.

3 situations... resource :user, only: :show and no id is passed or we return 404 error /url?page=1 we would either not require it or return a custom error Missing payload attribute we should automatically infer the expected type and value of the source object e.g. source = { pointer: '/data/attributes/user_id}

This would then return

{
  "errors": [
    {
      "title": "Invalid user_id",
      "detail": "User can't be blank",
      "source": {
        "pointer": "/data/attributes/user_id"
      }
    }
  ],
  "jsonapi": {
    "version": "1.0"
  }
}
JoeWoodward commented 6 years ago

Been investigating and although this seems like it would be useful for debugging it's actually against the RFC6901 definition. A pointer can only point to a JSON key and cannot point to a missing key.

However, maybe it can be returned in the meta to help with debugging

JoeWoodward commented 6 years ago

Actually I think it should reference '/data/attributes' http://jsonapi.org/examples/#error-objects-source-usage

{
  "errors": [
    {
      "source": { "pointer": "" },
      "detail":  "Missing `data` Member at document's top level."
    }
  ]
}

It uses source to point to the top-level of the document (""). (Pointing to “/” would be an appropriate reference to the string "some value" in the request document {"": "some value"}. Pointing to "/data" would be invalid because the request document did not have a value at "/data", and source is always given with reference to the request document.)

Following this format if @pointer is missing from the active record errors serializer class then we can assume that it should be pointing to the /data/attributes node

JoeWoodward commented 6 years ago

https://github.com/jsonapi-rb/jsonapi-rails/pull/94

bsylvain commented 5 years ago

Also if the parameter has been aliased :

   attribute :reply do
       @object.content
     end

The source is empty. There should be a way to set alias for errors also

beauby commented 5 years ago

@bsylvain This should be the case, providing you use jsonapi-rb deserializers. Could you show a minimal example where this fails?