Implementing RESTful field query-string parameter - rest

Based on the recommendation by APIGEE in their RESTful API Design blog post I wish to implement the fields query-string parameter to allow mobile application clients to restrict the content returned from a single RESTful API call. For example:
domain.site.com/rest/accounts/{id}?fields=name,id,age
If the fields parameter is omitted then a complete account resource will be returned. My question is how would I implement this on the server using Jersey (for example). Since Jersey makes it easy to return an Account POJO but I am unsure how to restrict the fields of the resulting JSON object based on the 'fields' query-string parameter.

There's not an automatic way to do it. Your service should load the entire object and then null out the fields you dont' want. Make sure the beans are annotated to ignore null fields in the json serialization and then return the object after you've modified it to remove the fields you dont' want.

Related

Implementing REST "fields" query param with Mapstruct

I am trying to implement REST query param "fields" with Mapstruct. The REST "fields" query param by convention lets you specify as its value a comma separated list of the fields of the entity you want in the response when you are preforming a GET request on an entity. This is opposed to returning all the fields of entity, which is what happens when "fields" query parameter is omitted.
Example:
GET locahost/blah/1
Response {"a":"1", "b":"2", c:"3"}
GET local/blah/1?fields=a,c
Response {"a":"1", "c":"3"}
So what I want Mapstruct to do is only map the bean's fields who's fields' names I specify. Note I need to be able to specify the bean's fields' names I want to map at runtime. Why? The fields I wish to map change from call to call of the GET method.
From what I read in the MapStruct documentation, you can specify what fields to map or not map with annotations. Unfortunately you can't change the annotation value at runtime (It maybe possible through reflection, but it feels should be a better way).
Given what I want to do, does anyone know how I can specify at runtime what fields are mapped?
Or alternately does anyone know a better way of implementing the REST "fields" query param?
I Look forward to reading the responses. If you have any questions or need clarifications just ask 🙂.
Regards,
Ben.
Thinking about this, I think that it doesn't make sense. As MapStruct generates the mapper classes at build time and therefore can't changing the mapping process at runtime. Is this right?

New DTO or Field Selector for API?

I am working on new API, but I am stuck with the choice for enabling Projection support.
my Entity User contains some properties and have some relationships too.
What should be the preferred approach for API?
Approach1
myApi.com/User/Fields="Id,Name,Email"
it returns my UserDTO with just populating Id,Name,Email and rest properties are null (I can further ignore the null before serializing JSON to send over the wire)
Approach2
myApi.com/User/GetCustomPropertiesABC"
it returns my UserCustomABCDTO . This Model contains just three properties for Id, Name, Email.
My question
I personally feel Approach 1 gives more Reuse quotient to API, Every time new selector required in Approach 2 will need to create a New DTO, But what is standard as per REST principles?
well, you could use ODATA for this, it would be perfect for it actually : http://www.odata.org/
Or, you could create an endpoint which accepts a request like your Approach 1 and returns dynamic. This way you don't have to worry about creating DTOs, you just create a new dynamic object, add whatever properties are required and return just that.
This keeps the returned entity small as it avoids who knows how many null or empty properties which don't really add anything useful.

Retrofit: Update only specific fields

I've been trying out Retrofit and I really it's simplicity.
However I have an otimization concern.
I'm using Parse for my backend and it has a pure Rest API.
When I want to update an object I use a PUT HTTP Request and pass in the body only the specific values I want to update.
However, using Retrofit I always have to serialize the entire object when passing it using the #Body annotation. If I have a very large object, this is very inneficient.
All the solutions I see is using Annotations to inform the Converter which fields are exposed. However this affects all requests and won't work if I have different update methods for updating different fields.
I think I have two options:
Pass the parameters I want to update as Form parameters and use
the #URLEncoded annotation. However this is not really RESTful
and I don't think Parse supports it.
Create an annotation to inform which fields should be added to JSON in the body. For doing this, how can I access the method's annotations in the Converter, in order to select which fields to serialize?
Retrofit uses Gson by default. And Gson excludes null values by default. So it shouldn't be a problem (unless you are using primitive types in your object)

Can EF 6 Data Annotations be different for POST than PUT or GET?

We are building a RESTful web service where there are sometimes different required fields for a POST than a PUT. For example, a field like CustomerSinceDate is allowed to be set on an insert, but not on an update. Is there is a way to set that up with Data Annotations?
EntityFramework does not (and should not) know anything about your web service. It deals only with what rules exist in the persistence layer.
What you are looking for is validation.
So in your REST service, you should check whether CustomerSinceData has been changed, and the entity is being updated. If so, you should throw an Exception with an appropriate message to the consumer.
Here is an article on writing your own DataAnnotations, if you prefer using those:
http://msdn.microsoft.com/en-us/data/jj819164#attributes
Otherwise, take a look at this article on how to write your own custom validation: http://msdn.microsoft.com/en-us/data/gg193959.aspx
(in particular, the section on IValidatableObject).
Your rule could be formulated as (pseudo code)
//if object exists in db AND CustomerSinceData has changed
DataAnnotations will get you a long way, but can be tedious to write if you are writing business logic that will never be reused anywhere else.

how do I prevent spring mvc overwriting sessionattributes from request

I have an MVC spring application where the user logs on, this stores a User #SessionAttribute , which I refer to subsequently e.g. when updating a Customer object in a POST request I want the session User info to add to this object.
My problem is when I access the #ModelAttribute("user") User object in the customer POST, spring has bound request parameters into it i.e. the User.name has the value of the Customer.name from the submitted form.
NB I've kind of hacked this in that all controllers are subclasses of my AppController, which is where the #SessionAttributes are declared. But the principle would be the same if it was a single controller.
So can I prevent spring binding form:customer name value to User.name?
(I suspect webflow would be a more suitable framework for this, but don't have the time available right now to rewrite using this)
You can allow or disallow binding of certain fields of your model attributes using #InitBinder:
#InitBinder("user")
public void configureBindingOfUser(WebDataBinder binder) {
binder.setAllowedFields(); // No fields allowed
}
However, I don't think it's a good idea to use #SessionAttributes to store the current user or other similar objects. #SessionAttributes was originally designed to maintain state of form-backing objects between GET and POST requests, not as a general purpose way to access a session.
Perhaps it would be better to use session-scoped beans or custom argument resolvers to access this kind of information.