Apache AVRO with Rest

纵饮孤独 提交于 2020-11-30 12:44:05

问题


I am evaluating using Apache AVRO for my Jersey REST services. I am using Springboot with Jersey REST.

Currently I am accepting JSON as input which are converted to Java Pojos using the Jackson object mapper.

I have looked in different places but I cannot find any example that is using Apache AVRO with a Jersey end point.

I have found this Github repository (https://github.com/FasterXML/jackson-dataformats-binary/) which has Apache AVRO plugin.

I still cannot find any good example as how to integrate this. Has anyone used Apache AVRO with Jersey? If yes, is there any example I can use?


回答1:


To start , two things need to happen:

  1. You need to develop a custom ObjectMapper after the fashion of the Avro schema format
  2. 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.




回答2:


There is a comprehensive demo (which I wrote) on how to use avro in a JAX-RS REST service at. The JAX-RS message body readers and writers for avro are implemented at and they do support avro binary, json, idiomatic json, csv where applicable. They do provide full support for schema evolution and projections (via the http accept header). There is a list of articles that explain in more detail the demonstrated concepts at. Also this demo project runs live on GKE at, you can browse at the openapi at. Avro is being used in the project for everything, for logs, for metrics, for profiling.



来源:https://stackoverflow.com/questions/45898453/apache-avro-with-rest

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!