Implementing REST "fields" query param with Mapstruct - 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?

Related

Spring Data JPA NamedNativeQuery with SqlResultSetMapping and externalized query

I have a situation where I am making a read request to a database with a long, complex query that needs to map to a complex object. Based on my research, it looks like I want to use #SqlResultSetMapping to handle the mapping, but I would like to put my query into the jpa-named-queries.properties file because it is so long. I can only find examples of #SqlResultSetMapping with #NamedNativeQuery that shows the query passed into the query parameter of the annotation as a string. Is it possible to use #SqlResultSetMapping with an externalized query, and if so, can anyone provide and example of how to do this? Thanks!

Projecting multiple fields to a POJO

Is there a way in hibernate-search 6 to project multiple fields and map them directly to a POJO object or I should handle it by myself. I'm not sure that I understand the composite method described in the documentation. For example I can do something like that:
SearchResult<List<?>> result = searchSession.search(indicies)
.select(f -> f.composite(f.field("field1"), f.field("field2"), f.field("field3"),f.field("field4")))
.where(SearchPredicateFactory::matchAll)
.fetch(20)
And then I can manually map the returned List of fields to a POJO. But is there a more fancy way to do that without the need to manually loop through the list of fields and set them to the POJO instance?
At the moment projecting to a POJO is only possible for fairly simple POJOs, with up to three fields, using the syntax shown in the documentation. For more fields than that, you have to go through a List.
If you're using the Elasticsearch backend, you can theoretically retrieve the document as a JsonObject and then use Gson to map it to a POJO.
There are plans to offer more fancy solutions, but we're not there yet.

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)

How to filter GWT requestFactory results?

I have a question about how to do data filtering with RequestFactory in GWT. I am currently working on an application which is backed by a MySQL database. My persistence layer is based on JPA/Hibernate. I am using RequestFactory to query my database for all my listing-related operations.
So for example, I have a Person object : In my PersonRequestContext I have a method which allows me to list persons. The method signature is :
Request<List<PersonProxy>> listPersons(Integer firstResult, Integer maxResults);
As you may have guessed, the corresponding query is something like this :
entityManager.createQuery("SELECT p FROM Person p ORDER BY p.id").setFirstResult(firstResult).setMaxResults(maxResults).getResultList();
Now, I would like to filter the result based on table columns. So I wanted to use some kind of Filter class abstraction to solve it. The problem is that as we all know, it's not possible to pass non-primitive objects in to the requestFactory method.
Have you ever experienced this kind of thing ? And how did you deal with it to solve the problem?
Your assertion that only primitive types can be passed to a Request method is incorrect. See the documentation on transportable types. You can create a ValueProxy hierarchy to model your filters.