RESTful API - Correct behaviour when spurious/not requested parameters are passed in the request

Viewed 26427

We are developing a RESTful api that accepts query parameters in the request in the form of JSON encoded data.

We were wondering what is the correct behaviour when non requested/not expected parameters are passed along with the required ones.

For example, we may require that a PUT request on a given endpoint have to provide exactly two values respectively for the keys name and surname:

{
    "name": "Jeff",
    "surname": "Atwood"
}

What if a spurious key is passed too, like color in the example below?

{
    "name": "Jeff",
    "surname": "Atwood",

    "color": "red"
}

The value for color is not expected, neither documented.

Should we ignore it or reject the request with a BAD_REQUEST 400 status error?

We can assert that the request is bad because it doesn't conform to the documentation. And probably the API user should be warned about it (She passed the value, she'll expects something for that.)

But we can assert too that the request can be accepted because, as the required parameters are all provided, it can be fulfilled.

6 Answers

Imagine I have the following JSON schema:

{
   "frequency": "YEARLY",
   "date": 23,
   "month": "MAY",
}

The frequency attribute accepts "WEEKLY", "MONTHLY" and "YEARLY" value. The expected payload for "WEEKLY" frequency value is:

{
   "frequency": "WEEKLY",
   "day": "MONDAY",
}

And the expected payload for "MONTHLY" frequency value is:

{
   "frequency": "MONTHLY",
   "date": 23,
}

Give the above JSON schema, typically I will have need a POJO containing frequency, day, date, and month fields for deserialization.

If the received payload is:

{
   "frequency": "MONTHLY",
   "day": "MONDAY",
   "date": 23,
   "year": 2018
}

I will throw an error on "day" attribute because I will never know the intention of the sender:

  1. frequency: "WEEKLY" and day: "MONDAY" (incorrect frequency value entered), or
  2. frequency: "MONTHLY" and date: 23

For the "year" attribute, I don't really have choice. Even if I wish to throw an error for that attribute, I may not be able to. It's ignored by the JSON serialization/deserialization library as my POJO has no such attribute. And this is the behavior of GSON and it makes sense given the design decision.

Navigating the Json tree or the target Type Tree while deserializing

When you are deserializing a Json string into an object of desired type, you can either navigate the tree of the input, or the type tree of the desired type. Gson uses the latter approach of navigating the type of the target object. This keeps you in tight control of instantiating only the type of objects that you are expecting (essentially validating the input against the expected "schema"). By doing this, you also ignore any extra fields that the Json input has but were not expected.

As part of Gson, we wrote a general purpose ObjectNavigator that can take any object and navigate through its fields calling a visitor of your choice.

Extracted from GSON Design Document

Related