Search code examples
restapihttpplayframework-2.0api-design

How to handle optional body with PUT or DELETE HTTP Requests (in a Play Application)?


reservation is a resource with 4 fields They are id, dataCenter, startDate, endDate

I wish to handle both types of requests:

  1. In which there is a body with a list of dataCenters

  2. In which they don't send a body (in this case I will perform the operation on all dataCenters which are present in the database).

Without body:

PUT /reservation/123/end

DELETE /reservation/123

With body:

PUT /reservation/123/end

{
    "dataCenters": ["AMS", "CLT"]
}

DELETE /reservation

{
    "dataCenters": ["AMS", "CLT"]
}

The problem being the server expects the body to be a valid JSON even when there is no body (which isn't the case when the body is empty). What would be the best way to handle this use case?


Solution

  • I found one possible solution, not a clean one, but works.

    For PUT

        Json
        .fromJson[OptionalDatacenters](request.body.asJson.getOrElse(JsArray()))
        .getOrElse(OptionalDatacenters(None))
        .dataCenters
    

    For DELETE

    Action.async(parse.raw) { request =>
      val dataCenters =
        request.body
          .asBytes()
          .map(
            bytes =>
              if (bytes.size > 1) Json.parse(bytes.toArray).as[OptionalDatacenters]
              else OptionalDatacenters(None)
          )
          .getOrElse(OptionalDatacenters(None))
          .dataCenters