Domino-rest use JaxRs @Produces and @Consumes and By default all service methods are mapped to produce or consume MediaType.APPLICATION_JSON which can be omitted, since the default serialization/deserialization in domino-rest is JSON, domino-rest supports both JSON and plain text by default but to use any other format writing custom (de)serializers is required and we utilize domino-rest RequestWriter/ResponseReader for that.
If our API expect the request body to be in a format that is not JSON or plain text we can provide a custom serializer or writer that implements the generic interface RequestWriter<T>
For example if we need the update method to send the movie in the body in xml format instead of JSON, we introduce a writer class :
@RequestFactory
public interface MoviesService {
@Path("library/movies/:movieName")
@GET
Movie getMovieByName(@PathParam("movieName") String movieName);
@Path("library/movies")
@GET
List<Movie> listMovies();
@Path("library/movies/:name")
@PUT
@SuccessCodes({200})
void updateMovie(@beanParam @RequestBody Movie movie);
}
Then in the service definition, we change the @Consumes and specify the writer using the @Writer annotation :
MoviesServiceFactory.INSTANCE
.getMovieByName("hulk")
.onSuccess(movie ->{})
.send();
In case we cant add the @Writer annotation on the JAX-RS resource method we can define the writer externally using the CustomMapper class like the following :
@Path("second-root-path")
public interface SecondService {
@Path("second-path")
SomeResponse secondRequest();
}
If our API should return the response body in a format that is not JSON or plain text we can provide a custom deserializer or reader that implements the generic interface ResponseReader<T>
For example if we need the update method to read the movie from the response body in xml format instead of JSON, we introduce a reader class :
import javax.ws.rs.FormParam;
public class SampleMultipartRequest {
@FormParam("sampleObjectJson")
private SampleObject sampleObject;
@FormParam("file")
private byte[] fileContent;
@FormParam("size")
private int size;
public SampleObject getSampleObject() {
return sampleObject;
}
public void setSampleObject(SampleObject sampleObject) {
this.sampleObject = sampleObject;
}
public byte[] getFileContent() {
return fileContent;
}
public void setFileContent(byte[] fileContent) {
this.fileContent = fileContent;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
}
Then in the service definition, we change the @Produces and specify the reader using the @Reader annotation :
@RequestFactory
public interface MoviesService {
@Path("library/movies/:movieName")
@GET
@Produce(MediaType.APPLICATION_XML)
@Reader(XmlMovieReader.class)
Movie getMovieByName(@PathParam("movieName") String movieName);
@Path("library/movies")
@GET
List<Movie> listMovies();
@Path("movies/:name")
@PUT
@Consumes(MediaType.APPLICATION_XML)
@Writer(MovieXmlWriter.class)
void updateMovie(@BeanParam @RequestBody Movie movie);
}
In case we cant add the @Reader annotation on the JAX-RS resource method we can define the reader externally using the CustomMapper class like the following :
CustomMapper.matcher(meta -> MoviesService.class.equals(meta.getServiceClass())
&& MediaType.APPLICATION_ATOM_XML.equals(meta.getProduce())
&& Movie.class.equals(meta.getResponseClass()))
.reader(() -> new XmlMovieReader());