Apache AVRO with Rest
To start , two things need to happen:
- You need to develop a custom
ObjectMapper
after the fashion of the Avro schema format - You need to supply that custom
ObjectMapper
to Jersey.
That should look something like this:
@Provider
public class AvroMapperProvider implements ContextResolver<ObjectMapper> {
final AvroMapper avroMapper = new AvroMapper();
@Override
public ObjectMapper getContext(Class<?> type) {
return avroMapper;
}
}
Configure your application to use Jackson as the message handler:
public class MyApplication extends ResourceConfig {
public MyApplication() {
super(JacksonFeature.class,AvroMapperProvider.class);
}
}
Alternatively, you can implement a custom MessageBodyReader
and MessageBodyWriter
that allows you to directly process the payloads on the way in and out:
public class AvroMessageReader implements MessageBodyReader<Person> {
AvroSchema schema;
final AvroMapper avroMapper = new AvroMapper();
public AvroMessageReader(){
schema = avroMapper.schemaFor(Person.class); //generates an Avro schema from the POJO class.
}
@Override
public boolean isReadable(Class<?> type, Type type1, Annotation[] antns, MediaType mt) {
return type == Person.class; //determines that this reader can handle the Person class.
}
@Override
public Person readFrom(Class<Person> type, Type type1, Annotation[] antns, MediaType mt, MultivaluedMap<String, String> mm, InputStream in) throws IOException, WebApplicationException {
return avroMapper.reader(schema).readValue(in);
}
}
Here, we generate an avro schema from a hypothetical Person class. The JAX-RS runtime will select this reader based on the response from isReadable
.
You can then inject the MessageBodyWorkers
component into your service implementation class:
@Path("app")
public static class BodyReaderTest{
@Context
private MessageBodyWorkers workers;
@POST
@Produces("avro/binary")
@Consumes("avro/binary")
public String processMessage() {
workers.getMessageBodyReader(Person.class, Person.class, new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE);
}
}
To answer your last comment: Setting the mime type on your handler to the recommended avro/binary ought to do it.