Handle Links in Restful Webservice Client - rest

I'm implementing a client to a restful webservice, that returns results in a linked-list kind of way, where each element, besides the actual contents has a URI pointing to the next part of the result.
#XmlRootElement()
public class PagedResult<T> {
private List<T> values;
private URI next;
}
Using jax-rs(jersey) with jax-b there is plenty of documentation on how to create these links on the server side, but I'm not sure whats the preferred way to handle this on the client. I could obviously parse the URI and do the request myself, but that seems wrong.
Is there a simple way to get a getNext() method (returning PagedResult, not URI)?

Related

Authorization based on URL parameters in JAX-RS / Java EE?

We are working on a web application based on JAX-RS. We have multiple parameterized endpoints that access resources by resource ID and query some aspect of them. We restrict access to individual resources only to those users who do have the rights to that particular resource. At the moment we are doing this by programmatically / manually checking for said access at the start of the method. What are the best practices, or even just the possibilities, to do this in a declarative / automated way?
The current endpoints look something like this:
#GET
#Path("/resource/{resourceId}/getWhatever")
#Produces(MediaType.APPLICATION_JSON)
public String getWhatever(#PathParam("resourceId") String resourceId) throws Exception {
checkForResourceAccess(resourceId, userName and security and whatever);
String result = query whatever from resource;
return result;
}
#GET
#Path("/resource/{resourceId}/getAnotherThing")
#Produces(MediaType.APPLICATION_JSON)
public String getAnotherThing(#PathParam("resourceId") String resourceId) throws Exception {
checkForResourceAccess(resourceId, userName and security and whatever);
String result = query another thing from resource;
return result;
}
[...]
So far I was thinking about these solutions:
A custom JAAS LoginModule. No experience in this, not even sure if it possible.
An interceptor specifically to check access to resources. However this is not reusable, it is strongly coupled to resourceId. Feels like a hack really.
JAX-RS filters and interceptors to filter requests.
Separate #Path("resource/{resourceId}") service class for these endpoints. #PathParam("resourceId") field, and some kind of automated check for example in a #PostConstruct method.
Custom <auth-constraint> if possible at all.
The situation is somewhat complicated by the fact that we use SAML 2.0 for Single Sign On authentication.
So, what would be the best practices, or even possibilities, to fulfill this authorization issue, while also conforming to Java EE specifications as much as possible?

How correctly implement a RESTful WS architecture using Spring MVC\Boot?

I am not so into RESTful web service and I have the following doubt about how to correctly implement RESTful style in my servics working on a Spring Boot application (Spring MVC is the same thing).
So basically I have some controller class like this:
#RestController
#RequestMapping("/RoomMedia")
public class RoomMediaController {
private static final Logger log = LoggerFactory.getLogger(RoomMediaController.class);
#Autowired
private RoomMediaService roomMediaService;
public RoomMediaController() {
log.debug("RoomMediaController init");
}
#RequestMapping(value = "getAllImagesByRoomId",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<byte[]>> getAllImagesByRoomId(Long roomId) throws DataAccessException {
log.debug("getAllImagesByRoomId START");
List<byte[]> result = roomMediaService.getRoomImageListById(roomId);
log.debug(result.toString());
log.debug("getAllImagesByRoomId END");
return ResponseEntity.ok(result);
}
}
I think that, also if the base idea is RESTful like, it can't be considered a true RESTful WS.
I think that the main problem is related to the endpoint: the getAllImagesByRoomId() method handle HTTP GET request toward URL like this: /RoomMedia/getAllImagesByRoomId?roomId=7
From what I have understand reading some tutorial this is not RESTful style because I have to access to a resource without passing parameter, I have to do someting like this:
/RoomMedia/Images/7
Is it my reasoning correct?
Moreover I think that the previous method is pretty trivial also in the implementation: this method return the list of all the images associated to a room having id=7(it is an application related to hotels).
From what I have understand also its logic is againts RESTful principles.
Is it better organize in the following way?
Doing a GET request like this:
/RoomMedia/7/Images/: I have to obtain the list of all the images associated to the room having id=7 as URI (or maybe is better handle a path like /7/RoomMedia/Images/ ?).
/RoomMedia/7/Images/1 I obtain the image with the id=1 associated to the room having id=7.
Are al these reasoning correct or am I missing something?
your assumtions are correct. Which of the mapping that you suggest, is deppending totaly on how your model is. Martin Fowler has a nice article about the Richardson Maturity Model which is sum up as:
Level 1 tackles the question of handling complexity by using divide and conquer, breaking a large service endpoint down into multiple resources.
Level 2 introduces a standard set of verbs so that we handle similar situations in the same way, removing unnecessary variation.
Level 3 introduces discoverability, providing a way of making a protocol more self-documenting.
For your project you could use jhipster because its offer you the best of spring with angular under a REST-ful design.
URLs must not contain a verb. The verb is provided by the method, in your case - surprise, surprise - GET.
ByRoomId is pointless as well, because that's what ?roomId= says.
That leaves AllImages, where All is superfluous.
Which results in the URL /RoomMedia/Images?roomId=7. What's unclear is the relationship between RoomMedia and Images, if there is any. If RoomMedia refers to a room, then your suggestion /RoomMedia/7/Images/ would be correct.
/RoomMedia/7/Images/1 is questionable. It should rather be /Images/1. It's irrelevant in which room the image with the id 1 is in.
When you design a REST API, then the first thing to do is to think about all resources you want to expose and their relationships. After that the URLs will reveal themselves automatically, so to speak.

Post array of object to WCF Rest service using JSON?

Need to send a complex object having nested IList from Iphone in JSON format to WCF REST service. The Complex Object is defined as following:
public class BatchData
{
long BatchID;
List<Account> Accounts;
List<Contacts> Contacts;
}
Please let me know the Client side (IPhone) syntax to create the required JSON request and also the server side POST method implementation to handle such scenario ?
Thanks in advance.
For the server side: define an operation contract which takes an array of that type. Search for examples on WCF Rest services (you'll need to use the [WebInvoke] attribute to define your operation) and you'll find how to do it.
For the client side: you can send the request using the NSURLRequest class. And to create the appropriate JSON, you can look at the NSJSONSerialization class, which will help you to convert between arrays (NSArray) and dictionaries (NSDictionary) and the JSON you need to send to the service.

Combining URL and POST variables in ServiceStack

I am trying to convert an existing wcf rest api to ServiceStack, and having issues right out of the gate:
[Route("foo/{userId}","POST")]
public class MyInputModel : IReturnVoid
{
public string userId { get; set; }
public SomeOtherObject properties { get; set; }
}
The intention here is that I would provide the userId in the url, and an instance of SomeOtherObject in the post body. The error I get is
<Message>Could not deserialize 'application/xml' request using MyInputModel'
Error: System.Runtime.Serialization.SerializationException:
Error in line 1 position 42. Expecting element 'MyInputModel'
from namespace 'blahblahblah'.. Encountered 'Element' with name
'SomeOtherObject', namespace 'http://blahblahblah'.
The only things I can think of are to wrap my xml in a MyInputModel to make the serializer happy. This is not really an option for backwards compatibility.
I could also modify SomeOtherObject to be the top level input model, and put a UserId property in there, but this also feels suboptimal since it is an object used throughout the api, and is really not tied to a user id. It is also already published independently, so it would be painful to make changes there.
Is there any way to indicate that the root element of the posted data will be a SomeOtherObject insted of a MyInputModel? In WebApi this would be with the [FromBody] attributes and whatnot. Does servicestack have anything similar?
The purpose of a DTO is to auto-generate the wire format which is why ServiceStack requires the Request DTO to match the shape of the incoming request. Part of what makes ServiceStack so productive is that it's a code-first web service framework which encourages starting from C# and projecting out, i.e. your clients should bind to your web service outputs and not the other way round of mapping code-first models to existing schema inputs.
Having said that, the Serialization / Deserialization wiki page lists the different ways to override ServiceStack's default request binding with your own.
Access HTTP Request variables in any Service or Filter
Not everything needs to be mapped to a DTO as any HTTP Variable can still be accessed from the IHttpRequest available from any service or filter, i.e:
base.Request.QueryString
base.Request.FormData
base.Request.Headers[name]
base.Request.PathInfo
base.Request.AbsoluteUri

JAX-RS generic response and interface proxy

is there any way how to return generic describing entity type with the JAX-RS Response? Something like REST-Easy ClientReponse but JAX-RS standard and not implementation-specific class.
The thing is I want to call my REST service via its shared interface (created by some proxy provider) and returning only object does not allow add information I need. E.g. for creating resource via POST, I would like to return also URL to newly created resource and so on. Returing simple Response does not show what type of entity is stored within such response.
Response<MyObject> getMyObject(#PathParam("id" Integer id)
So far it seems that I will have to return simple Response and then create adapter which will simply call Response.getEntity(.class)
There is probably no such option...
GenericEntity allows you to return a generic. The actual type is held at runtime by GenericEntity, allowing the object to be serialized.
Here's a contrived example of how it can be used.
GenericEntity entity = new GenericEntity<Employee>(new Employee());
return Response.ok(entity).build();