Win a copy of Cross-Platform Desktop Applications: Using Node, Electron, and NW.js this week in the JavaScript forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Multiple (complex) objects as parameters in a RESTFul webservice (via POST)  RSS feed

 
Claude Moore
Ranch Hand
Posts: 874
8
IBM DB2 Java Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have defined a simple service method of an EJB interface exposed as RESTFul service:



but absolutely no luck.... I get a "Resource method assign tasks has more than one parameter representing a request body" error.
I'm using wildfly 10.0 as appserver, and on the client side I'm using Apache CFX to create a JAX-RS proxy to execute remote calls... but besides this, I wonder if it's even correct to try to send more than a single object parameter in a REST request (via Post, I mean).
Of course I would be able to incapsulate in some wrapper object both Employee and List parameters, but I don't like a black-box container as a mean to pass parameters.

Any hint ?
 
Ron McLeod
Saloon Keeper
Posts: 1561
221
Android Angular Framework Eclipse IDE Java Linux MySQL Database Redhat TypeScript
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If the employee resource cannot exist on its own and always must have tasks, you might want to combine the resources in to a EmployeeWithTasks resource.

If that is not a constrainst, then I would break-down this down in to multiple transactions: create an employee, create a task, create another task, etc.

Messaging would look something like this:
POST /api/employees HTTP/1.1
Content-Length: 49
Content-Type: application/json
{ "first-name":"Phillip", "last-name":"Larsen" }

HTTP/1.1 201 Created
Location: http://1.2.3.4:5678/api/employees/332
Content-Length: 0


POST /api/employees/332/tasks HTTP/1.1
Content-Length: 42
Content-Type: application/json
{ "task-name":"Mop floor", "duration":3 }

HTTP/1.1 201 Created
Location: http://1.2.3.4:5678/api/employees/332/tasks/1
Content-Length: 0


POST /api/employees/332/tasks HTTP/1.1
Content-Length: 44
Content-Type: application/json
{ "task-name":"Check doors", "duration":1 }

HTTP/1.1 201 Created
Location: http://1.2.3.4:5678/api/employees/332/tasks/2
Content-Length: 0
 
Ron McLeod
Saloon Keeper
Posts: 1561
221
Android Angular Framework Eclipse IDE Java Linux MySQL Database Redhat TypeScript
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Claude Moore wrote:Of course I would be able to incapsulate in some wrapper object both Employee and List parameters, but I don't like a black-box container as a mean to pass parameters.

If you really do need to send multiple resources in a single POST, you could send multipart content where the body contains multiple body parts.
 
Claude Moore
Ranch Hand
Posts: 874
8
IBM DB2 Java Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ron, thank you for your answers.Between two suggested approaches, I would prefer the first: this way, I would be able to let CXF generate a proxy and use it directly, with compile time parameters checking. The trade-off with this approach is that I can pass only a single complex object plus a number of IDs of related resources. At first glance, this may imply that any entity must be identified by a simple ID (to be used in a path parameter), and that I may need to load from a database all entities I could not pass as whole objects...
The second approach looks too much coarse grained...I could pass anything, loosing compile time checking mentioned above.. I don't like it much. But it may interesting to use it as generic request/response handler, coupled with Java dynamic proxies...what do you think about?
 
Ron McLeod
Saloon Keeper
Posts: 1561
221
Android Angular Framework Eclipse IDE Java Linux MySQL Database Redhat TypeScript
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Claude Moore wrote:The trade-off with this approach is that I can pass only a single complex object plus a number of IDs of related resources. At first glance, this may imply that any entity must be identified by a simple ID (to be used in a path parameter), and that I may need to load from a database all entities I could not pass as whole objects...

I don't understand how this would be a problem. Maybe you can explain why using a resource identifier in your transaction rather than the resource itself would make things more challenging.

The only time the client should need to pass (a representation of) the resource to the server is when the resource is first being created (transferred to) the server, or when it is being replaced/updated.
 
Claude Moore
Ranch Hand
Posts: 874
8
IBM DB2 Java Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't understand how this would be a problem. Maybe you can explain why using a resource identifier in your transaction rather than the resource itself would make things more challenging.

I think it would depend upon the actual scenario. In the example I posted, let us suppose that the assignment of the tasks to a given employee may succeed or not depending upon a certain information / property of the Employee. If I don't pass the whole entity, I need to reload data from the database (and this make take a little time)... of course that's not a big deal, anyway.

The only time the client should need to pass (a representation of) the resource to the server is when the resource is first being created (transferred to) the server, or when it is being replaced/updated.

And this proposition makes me think a lot... Would be right to say that to accomplish a correct RESTFul approach we must focus mainly on resources, and not on relations among resources ?
I would exclude that REST may be used only in stateful scenarios - when we would have a current Employee entity we are working on, it would be too limited...

Thanks again for your help !!

 
Ron McLeod
Saloon Keeper
Posts: 1561
221
Android Angular Framework Eclipse IDE Java Linux MySQL Database Redhat TypeScript
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Claude Moore wrote:In the example I posted, let us suppose that the assignment of the tasks to a given employee may succeed or not depending upon a certain information / property of the Employee. If I don't pass the whole entity, I need to reload data from the database (and this make take a little time)... of course that's not a big deal, anyway.

With that model, you are putting the burden (and trust) on the client-side to have provide to the correct Employee information to the server. How would the client obtain information? Probably by performing a the database dip, which was what you wanted to avoid.

Claude Moore wrote:And this proposition makes me think a lot... Would be right to say that to accomplish a correct RESTFul approach we must focus mainly on resources, and not on relations among resources ? I would exclude that REST may be used only in stateful scenarios - when we would have a current Employee entity we are working on, it would be too limited...

A RESTful API is built around the idea of resources, and often resources have relationships with other resources. For your Employee resource, when you return the resource for the employee, you could also provide links to any related resources, including Tasks and others:

GET /api/employees?last-name=Larsen&first-name=Phillip HTTP/1.1

HTTP/1.1 200 OK
Link: </api/employees/332>; rel="self"; title="Phillip Larsen"
Link: </api/employees/332/tasks>; rel="tasks"; title="Tasks"
Link: </api/employees/332/log>; rel="log"; title="Work Log"
Content-Type: application/json
Content-Length: 49
{ "first-name":"Phillip", "last-name":"Larsen" }


GET /api/employees/332/tasks HTTP/1.1

HTTP/1.1 200 OK
Link: </api/employees/332/tasks/1>; rel="task"; title="Mop floor"
Link: </api/employees/332/tasks/2>; rel="task"; title="Check doors"
Content-Length: 0
 
Claude Moore
Ranch Hand
Posts: 874
8
IBM DB2 Java Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks, your explanation helped me a lot.
 
Claude Moore
Ranch Hand
Posts: 874
8
IBM DB2 Java Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
... and IMHO this discussion deserves to become a Wiki.
I think it would be helpful for someone else.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!