Skip to content

Produces and Consumes

Ahmad K. Bawaneh edited this page Mar 16, 2020 · 5 revisions

Produces and Consumes

Domino-rest use JaxRs @Produces and @Consumes and By default all service methods are mapped to produce or consume MediaType.APPLICATION_JSON which is omitted, since the default serialization/deserialization in domino-rest is JSON, domino-rest supports both JSON and plain text by default but for using any other format will require writing custom (de)serializers using RequestWriter/ResponseReader

  • Writer

if want a service method to send the body in a format other than JSON we can write a custom serializer or writer by implementing the generic interface RequestWriter<T>

e.g if want the update method to send the movie in the body in xml format instead of JSON, we introduce a writer class :

    public class XmlMovieWriter implements RequestWriter<Movie>{
        @Override
        public String write(Movie request) {
            String movieXml = //convert the movie to xml
            return movieXml;
        }
    }

then in our service definition, we change the @Consumes and specify the writer using the @Writer annotation

@RequestFactory
public interface MoviesService {

    @Path("library/movies/:movieName")
    @GET
    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);
}

if we want to avoid the @Writer annotation on the JAX-RS resource method we can define the writer externally using the CustomMapper class like the following :

CustomMapper.matcher(meta -> MoviesService.class.equals(meta.getServiceClass())
                && MediaType.APPLICATION_ATOM_XML.equals(meta.getConsume())
                && Movie.class.equals(meta.getRequestClass()))
                .writer(() -> new XmlMovieWriter());
  • Reader

if want a service method to read the response body in a format other than JSON we can write a custom deserializer or reader by implementing the generic interface ResponseReader<T>

e.g if want the update method to read the movie in the body in xml format instead of JSON, we introduce a reader class :

    public class XmlMovieReader implements RequestReader<Movie>{
        @Override
        public Movie read(String request) {
            Movie movieFromXml = //convert the xml to Movie
            return movieFromXml;
        }
    }

then in our 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);
}

if we want to avoid the @Reader annotation on the JAX-RS resource method we can define the writer 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());