diminuta
diminuta

Reputation: 1583

Java REST service that accepts list of objects

I have to write a REST Service method that accepts a list of objects as parameter to calculate something and return a result.

I have so far:

@RequestMapping(value = "generateBill/{id}/{rates}")
public String generateBill(@PathVariable Long id, @PathVariable Rate rates[]) {
   // do things
   return "OK";
}

But I am sure that @PathVariable Rate rates[] is wrong.

I have to write the client part too and I also have no idea how to do it. It is the first time I have to write such a REST Service method.

Edit: Rate looks like this:

public class Rate {
   Long version;
   Double amount;
   Date validFrom;
   Date validUntil;
}

Upvotes: 1

Views: 15811

Answers (3)

You should put your objects in the body of a POST request instead of using the URL :

@RequestMapping(value = "generateBill/{id}", method = RequestMethod.POST)
public String generateBill(@PathVariable Long id, @RequestBody BillingRequest billingRequest) {
   // do things
}

Also, mapping directly a collection in the payload is not evolvable (you cannot add new "fields" outside the array), it's generally a good practice to wrap your array in a JSON object :

public class BillingRequest {
    List<Rate> rates;
    // Here you could add other fields in the future
}

Your HTTP request to call your service would look like this :

POST / HTTP/1.1
{  
  "rates" : [
     {
       "version" : 1,
       "amount" : 33.3,
       "validFrom" : "2016-01-01",
       "validUntil" : "2017-01-01" 
     },
     {
       "version" : 2,
       "amount" : 10.0,
       "validFrom" : "2016-02-01",
       "validUntil" : "2016-10-01" 
     }
   ] 
}

One last piece of advice about your model :

  • Use java.time.LocalDate (or jodatime) instead of java.util.Date. If you need date+time, use java.time.ZonedDateTime (DateTime if you use jodatime)
  • Use java.math.BigDecimal to represent exact numbers. Floating point numbers like Double can lose precision

EDIT : I would suggest using Instant rather than ZonedDateTime, which is a timestamp with UTC timezone. Unless of course your domain requires different timezones.

Upvotes: 4

Hrabosch
Hrabosch

Reputation: 1583

First solution:

@RequestMapping(value = "generateBill/{id}/{rates}", method=RequestMethod.GET)
public String generateBill(@PathVariable Long id, @PathVariable Rate[] rates) {
   // do things
   return "OK";
}

Or second one (more Java style;) ):

@RequestMapping(value = "generateBill/{id}/{rates}", method=RequestMethod.GET)
public String generateBill(@PathVariable Long id, @PathVariable List<Rate> rates) {
   // do things
   return "OK";
}

This one you can call like this:

GET: http://localhost:8080/public/generateBill/1/1,2,3,4 Where 1.2,3,4 replace with your values, it depends od that what exactly is Rate ;)


EDIT

After your update, it looks like that you want to have POST method (you are posting list of rates) and then here is already answered question. receiving json and deserializing as List of object at spring mvc controller

Upvotes: 3

Hristo Staykov
Hristo Staykov

Reputation: 974

Other solution is to use JSON String format as a parameter and parse it afterwards. Something like

[
{
"rates":1, "name":"rate1" }, {
"rates":2, "name":"rate2" }, {
"rates":3, "name":"rate3" } ]

and after that parse the json to your object.

Upvotes: 2

Related Questions