{"id":81675,"date":"2018-09-13T16:00:21","date_gmt":"2018-09-13T13:00:21","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=81675"},"modified":"2023-12-11T12:27:15","modified_gmt":"2023-12-11T10:27:15","slug":"microservices-java-developers-java-jvm-landscape","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2018\/09\/microservices-java-developers-java-jvm-landscape.html","title":{"rendered":"Microservices for Java Developers: The Java \/ JVM Landscape"},"content":{"rendered":"<h2><a name=\"introduction\"><\/a>1. Introduction<\/h2>\n<p>In the previous part of the tutorial we have covered a broad range of communication styles widely used while building <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservices<\/a>. It is time to put this knowledge into practical perspective by talking about most popular and battle-tested Java libraries and frameworks which may serve as the foundation of your <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservice architecture<\/a> implementation.<\/p>\n<p>Although there are quite a few old enough to remember the <a href=\"https:\/\/en.wikipedia.org\/wiki\/SOAP\">SOAP<\/a> era, many of the frameworks we are going to discuss shortly are fairly young, and often quite opinionated. The choice of which one is right for you is probably the most important decision you are going to make early on. Beside the <a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=370\">JAX-RS<\/a> specification (and more generic <a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=369\">Servlet<\/a> specification), there are no industry-wide standards to guarantee the interoperability between different frameworks and libraries on JVM platform, so make the call wisely.F3.1<\/p>\n<div class=\"toc\">\n<h3>Table Of Contents<\/h3>\n<dl>\n<dt><a href=\"#introduction\">1. Introduction<\/a><\/dt>\n<dt><a href=\"#resty\">2. Staying RESTy<\/a><\/dt>\n<dd>\n<dl>\n<dt><a href=\"#jaxrs\">2.1. JAX-RS: RESTful Java in the Enterprise<\/a><\/dt>\n<dt><a href=\"#cxf\">2.2. Apache CXF<\/a><\/dt>\n<dt><a href=\"#meecrowave\">2.3. Apache Meecrowave<\/a><\/dt>\n<dt><a href=\"#resteasy\">2.4. RESTEasy<\/a><\/dt>\n<dt><a href=\"#jersey\">2.5. Jersey <\/a><\/dt>\n<dt><a href=\"#dropwizard\">2.6. Dropwizard<\/a><\/dt>\n<dt><a href=\"#microprofile\">2.7. Eclipse Microprofile: thinking in microservices from the get-go<\/a><\/dt>\n<dt><a href=\"#webmvc\">2.8. Spring WebMvc \/ WebFlux<\/a><\/dt>\n<dt><a href=\"#spark\">2.9. Spark Java<\/a><\/dt>\n<dt><a href=\"#restlet\">2.10. Restlet<\/a><\/dt>\n<dt><a href=\"#vertx\">2.11. Vert.x<\/a><\/dt>\n<dt><a href=\"#play\">2.12. Play Framework<\/a><\/dt>\n<dt><a href=\"#akkahttp\">2.13. Akka HTTP<\/a><\/dt>\n<dt><a href=\"#micronaut\">2.14. Micronaut<\/a><\/dt>\n<\/dl>\n<\/dd>\n<dt><a href=\"#graphql\">3. GraphQL, the New Force <\/a><\/dt>\n<dd>\n<dl>\n<dt><a href=\"#sangria\">3.1. Sangria<\/a><\/dt>\n<dt><a href=\"#javagraphql\">3.2. graphql-java<\/a><\/dt>\n<\/dl>\n<\/dd>\n<dt><a href=\"#rpc\">4. The RPC Style<\/a><\/dt>\n<dd>\n<dl>\n<dt><a href=\"#javagrpc\">4.1. java-grpc<\/a><\/dt>\n<dt><a href=\"#reactivegrpc\">4.2. Reactive gRPC<\/a><\/dt>\n<dt><a href=\"#akkagrpc\">4.3. Akka gRPC<\/a><\/dt>\n<dt><a href=\"#bubbo\">4.4. Apache Dubbo<\/a><\/dt>\n<dt><a href=\"#finagle\">4.5. Finatra and Finagle<\/a><\/dt>\n<\/dl>\n<\/dd>\n<dt><a href=\"#messaging\">5. Messaging and Eventing<\/a><\/dt>\n<dd>\n<dl>\n<dt><a href=\"#axon\">5.1. Axon Framework<\/a><\/dt>\n<dt><a href=\"#lagom\">5.2. Lagom<\/a><\/dt>\n<dt><a href=\"#akka\">5.3. Akka<\/a><\/dt>\n<dt><a href=\"#zeromq\">5.4. ZeroMQ<\/a><\/dt>\n<dt><a href=\"#kafka\">5.5. Apache Kafka<\/a><\/dt>\n<dt><a href=\"#rabbitmq\">5.6. RabbitMQ and Apache Qpid<\/a><\/dt>\n<dt><a href=\"#activemq\">5.7. Apache ActiveMQ<\/a><\/dt>\n<dt><a href=\"#rocketmq\">5.8. Apache RocketMQ<\/a><\/dt>\n<dt><a href=\"#nats\">5.9. NATS<\/a><\/dt>\n<dt><a href=\"#nsq\">5.10. NSQ<\/a><\/dt>\n<\/dl>\n<\/dd>\n<dt><a href=\"#all\">6. Get It All<\/a><\/dt>\n<dd>\n<dl>\n<dt><a href=\"#camel\">6.1. Apache Camel<\/a><\/dt>\n<dt><a href=\"#spring\">6.2. Spring Integration<\/a><\/dt>\n<\/dl>\n<\/dd>\n<dt><a href=\"#cloud\">7. What about Cloud?<\/a><\/dt>\n<dt><a href=\"#things\">8. But There Are a Lot More \u2026<\/a><\/dt>\n<dt><a href=\"#conclusions\">9. Conclusions<\/a><\/dt>\n<dt><a href=\"#next\">10. What\u2019s next <\/a><\/dt>\n<\/dl>\n<\/div>\n<p>There will not be any comparison to promote one framework or library over another since each has own goals, philosophy, community, release cycles, roadmaps, integrations, scalability and performance characteristics. There are just too many factors to account for, taking into the context the application and organization specifics.<\/p>\n<p>However, a couple of valuable resources could be of a great help. The <a href=\"https:\/\/github.com\/mfornos\/awesome-microservices\">Awesome Microservices<\/a> repository is a terrific curated list of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservice architecture<\/a> related principles and technologies. In the same vein, the <a href=\"https:\/\/www.techempower.com\/\">TechEmpower<\/a>\u2019s <a href=\"https:\/\/www.techempower.com\/benchmarks\/\">Web Framework Benchmarks<\/a> provides a number of interesting and useful insights regarding the performance of several web application platforms and frameworks, and not only the JVMs ones.<\/p>\n<h2><a name=\"resty\"><\/a>2. Staying RESTy<\/h2>\n<p>The most crowded space is occupied by the frameworks and libraries which promote <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">REST architectural style<\/a> over <a href=\"https:\/\/en.wikipedia.org\/wiki\/Hypertext_Transfer_Protocol\">HTTP<\/a> protocol. Nearly all the nominees in this category are very matured and well-established brands, deployed in productions for years.<\/p>\n<h3><a name=\"jaxrs\"><\/a>2.1. JAX-RS: RESTful Java in the Enterprise<\/h3>\n<p>The <a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=370\">JAX-RS<\/a> specification, also known as <a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=370\">JSR-370<\/a> (and previously outlined in the <a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=339\">JSR-339<\/a> and <a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=311\">JSR-311<\/a>), defines a set of Java APIs for the development of web services built according to the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">REST architectural style<\/a>. It is fairly successful effort with many implementations available to select from and, arguably, the number one preference in the enterprise world.<\/p>\n<p>The <a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=370\">JAX-RS<\/a> APIs are driven by Java annotations and generally could be ported from one framework to another quite smoothly. In addition, there is tight integration with other Java platform specifications, like <a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=365\">Contexts and Dependency Injection for Java<\/a> (<a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=365\">JSR-365<\/a>), <a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=380\">Bean Validation<\/a> (<a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=380\">JSR-380<\/a>), <a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=374\">Java API for JSON Processing<\/a> (<a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=374\">JSR-374<\/a>) to name a few.<\/p>\n<p>Getting back to the imaginable library management web APIs we have talked about in the <a href=\"https:\/\/www.javacodegeeks.com\/2018\/08\/microservices-java-developers-microservices-communication.html\">previous part of the tutorial<\/a>, the typical (but very simplified) <a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=370\">JAX-RS<\/a> web service implementation may look like this:<\/p>\n<pre class=\"brush:java\">@Path(\"\/library\")\npublic class LibraryRestService {\n    @Inject private LibraryService libraryService;\n\n    @GET\n    @Path(\"\/books\")\n    @Produces(MediaType.APPLICATION_JSON)\n    public Collection&lt;Book&gt; getAll() {\n        return libraryService.getBooks();\n    }\n    \n    @POST\n    @Path(\"\/books\")\n    @Produces(MediaType.APPLICATION_JSON)\n    public Response addBook(@Context UriInfo uriInfo, Book payload) {\n        final Book book = libraryService.addBook(payload);\n        \n        return Response\n            .created(\n                uriInfo\n                    .getRequestUriBuilder()\n                    .path(book.getIsbn())\n                    .build())\n            .entity(book)\n            .build();    }\n    \n    @GET\n    @Path(\"\/books\/{isbn}\")\n    @Produces(MediaType.APPLICATION_JSON)\n    public Book findBook(@PathParam(\"isbn\") String isbn) {\n        return libraryService\n            .findBook(isbn)\n            .orElseThrow(() -&gt; new NotFoundException(\"No book found for ISBN: \" + isbn));\n    }\n}\n<\/pre>\n<p>It should work on any framework which is fully compliant with the latest <a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=370\">JAX-RS 2.1<\/a> specification (<a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=370\">JSR-370<\/a>) so let us take it from there.<\/p>\n<h3><a name=\"cxf\"><\/a>2.2. Apache CXF<\/h3>\n<p><a href=\"http:\/\/cxf.apache.org\/\">Apache CXF<\/a>, an open source services framework, celebrates its 10<sup>th<\/sup> anniversary this year! <a href=\"http:\/\/cxf.apache.org\/\">Apache CXF<\/a> helps to build and develop services using frontend programming APIs, like <a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=224\">JAX-WS<\/a> and <a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=370\">JAX-RS<\/a>, which can speak a variety of protocols such as <a href=\"https:\/\/en.wikipedia.org\/wiki\/SOAP\">SOAP<\/a>, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">REST<\/a>, <a href=\"https:\/\/en.wikipedia.org\/wiki\/SSE\">SSE<\/a> (even <a href=\"https:\/\/en.wikipedia.org\/wiki\/Common_Object_Request_Broker_Architecture\">CORBA<\/a>) and work over a variety of transports such as &nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Hypertext_Transfer_Protocol\">HTTP<\/a>, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Java_Message_Service\">JMS<\/a> or <a href=\"https:\/\/en.wikipedia.org\/wiki\/Java_Business_Integration\">JBI<\/a>.<\/p>\n<p>What makes <a href=\"http:\/\/cxf.apache.org\/\">Apache CXF<\/a> a great fit for <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservices<\/a> is the fact that it has outstanding integrations with many other projects, notably: <a href=\"http:\/\/cxf.apache.org\/docs\/openapifeature.html\">OpenAPI<\/a> for contract-driven development, <a href=\"https:\/\/cwiki.apache.org\/confluence\/display\/CXF20DOC\/Using+OpenZipkin+Brave\">Brave<\/a> \/ <a href=\"https:\/\/cwiki.apache.org\/confluence\/display\/CXF20DOC\/Using+OpenTracing\">OpenTracing<\/a> \/ <a href=\"http:\/\/cxf.apache.org\/docs\/using-apache-htrace.html\">Apache HTrace<\/a> for distributed tracing, <a href=\"https:\/\/cwiki.apache.org\/confluence\/display\/CXF20DOC\/JAX-RS+JOSE\">JOSE<\/a> \/ <a href=\"http:\/\/cxf.apache.org\/docs\/jax-rs-oauth2.html\">OAuth2<\/a> \/ <a href=\"http:\/\/cxf.apache.org\/docs\/jax-rs-oidc.html\">OpenID Connect<\/a> for security.<\/p>\n<h3><a name=\"meecrowave\"><\/a>2.3. Apache Meecrowave<\/h3>\n<p><a href=\"http:\/\/openwebbeans.apache.org\/meecrowave\/index.html\">Meecrowave<\/a> is a very lightweight, easy to use <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservices<\/a> framework<strong>, <\/strong>built exclusively on top of other great <a href=\"http:\/\/www.apache.org\/\">Apache<\/a> projects: <a href=\"http:\/\/openwebbeans.apache.org\/\">Apache OpenWebBeans<\/a> (<a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=365\">CDI 2.0<\/a>), <a href=\"http:\/\/cxf.apache.org\/\">Apache CXF<\/a> (<a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=370\">JAX-RS 2.1<\/a>), and <a href=\"https:\/\/johnzon.apache.org\/\">Apache Johnzon<\/a> (<a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=353\">JSON-P<\/a>). It significantly reduces the development time since all the necessary pieces are already wired together.<\/p>\n<h3><a name=\"resteasy\"><\/a>2.4. RESTEasy<\/h3>\n<p><a href=\"https:\/\/resteasy.github.io\/\">RESTEasy<\/a> from <a href=\"https:\/\/developer.jboss.org\/welcome\">RedHat \/ JBoss<\/a> is another fully certified and portable implementation of the <a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=370\">JAX-RS 2.1<\/a> specification. One of the advantages of the <a href=\"https:\/\/resteasy.github.io\/\">RESTEasy<\/a> framework is tighter integration with <a href=\"http:\/\/www.wildfly.org\/\">WildFly Application Server<\/a>, in case it might be important in your context.<\/p>\n<h3><a name=\"jersey\"><\/a>2.5. Jersey<\/h3>\n<p><a href=\"https:\/\/jersey.github.io\/\">Jersey<\/a> is an open source, production quality framework for developing <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">RESTful web services<\/a> in Java. In fact, it serves as a <a href=\"https:\/\/github.com\/jax-rs\">JAX-RS<\/a> (<a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=370\">JSR-370<\/a>, <a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=339\">JSR-339<\/a> and <a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=311\">JSR-311<\/a>) reference implementation. Similarly to other frameworks, <a href=\"https:\/\/jersey.github.io\/\">Jersey<\/a> goes way beyond just being <a href=\"https:\/\/github.com\/jax-rs\">JAX-RS<\/a> implementation and provides additional features, extensions and utilities to further simplify the development of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">RESTful<\/a> web APIs and clients.<\/p>\n<h3><a name=\"dropwizard\"><\/a>2.6. Dropwizard<\/h3>\n<p><a href=\"https:\/\/www.dropwizard.io\/\">Dropwizard<\/a> is yet another great Java framework for developing <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">RESTful web services and APIs<\/a> with the emphasis on the operational friendliness and high performance. It is built on top of <a href=\"https:\/\/jersey.github.io\/\">Jersey<\/a> framework and combines together best of breed libraries from the entire Java ecosystem. In that sense, it is quite opinionated, but at the same time known to be simple, stable<strong>, <\/strong>mature and light-weight<strong>.<\/strong><\/p>\n<blockquote>\n<p><em><a href=\"https:\/\/www.dropwizard.io\/\">Dropwizard<\/a> has out-of-the-box support for sophisticated configuration, application metrics, logging, operational tools, and much more, allowing you and your team to ship a production-quality web service in the shortest time possible. &#8211; <\/em><a href=\"https:\/\/www.dropwizard.io\/1.3.5\/docs\"><em>https:\/\/www.dropwizard.io\/1.3.5\/docs<\/em><\/a><\/p>\n<\/blockquote>\n<p>It is worth noting that <a href=\"https:\/\/www.dropwizard.io\/\">Dropwizard<\/a> truly established the instrumentation and monitoring baseline for modern Java applications (you may have heard about <a href=\"https:\/\/metrics.dropwizard.io\/\">Metrics<\/a> library born from it) and is really good choice for building <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservices<\/a>.<\/p>\n<h3><a name=\"microprofile\"><\/a>2.7. Eclipse Microprofile: thinking in microservices from the get-go<\/h3>\n<p>While talking about <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservices<\/a> in Java universe it is impossible not to mention very recent initiative undertaken by <a href=\"http:\/\/www.eclipse.org\/\">Eclipse Foundation<\/a>, known as <a href=\"https:\/\/microprofile.io\">MicroProfile<\/a>.<\/p>\n<blockquote>\n<p><em>The MicroProfile is a baseline platform definition that optimizes Enterprise Java for a microservices architecture and delivers application portability across multiple MicroProfile runtimes. The initially planned baseline is JAX-RS + CDI + JSON-P, with the intent of community having an active role in the MicroProfile definition and roadmap. &#8211; <\/em><a href=\"https:\/\/microprofile.io\/faq\"><em>https:\/\/microprofile.io\/faq<\/em><\/a><\/p>\n<\/blockquote>\n<p>The primary goal of <a href=\"https:\/\/microprofile.io\">MicroProfile<\/a> is to accelerate the pace of innovation in the space of the enterprise Java, which traditionally is suffering from very slow processes. It is certainly worth keeping an eye on.<\/p>\n<h3><a name=\"webmvc\"><\/a>2.8. Spring WebMvc \/ WebFlux<\/h3>\n<p>Long time ago <a href=\"https:\/\/spring.io\/\">Spring Framework<\/a>, initially the implementation of the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Inversion_of_control\">inversion of control<\/a> (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Inversion_of_control\">IoC<\/a>) design principle, had shaken the world of the enterprise Java, filled with monstrous frameworks and specifications.&nbsp; It provided an easy and straightforward way to use <a href=\"https:\/\/en.wikipedia.org\/wiki\/Dependency_injection\">dependency injection<\/a> capabilities in Java applications.<\/p>\n<p>The <a href=\"https:\/\/en.wikipedia.org\/wiki\/Inversion_of_control\">IoC<\/a> \u00ad\u00ad\u00adand <a href=\"https:\/\/en.wikipedia.org\/wiki\/Dependency_injection\">dependency injection<\/a> are still at the core of <a href=\"https:\/\/spring.io\/\">Spring Framework<\/a> but there are <a href=\"https:\/\/spring.io\/projects\">so many projects<\/a> under its umbrella that nowadays it is more like a platform than anything else. As for this section, the one we are interested in is <a href=\"https:\/\/docs.spring.io\/spring\/docs\/current\/spring-framework-reference\/web.html\">Spring Web MVC<\/a>, the original web framework built on the <a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=369\">Servlet<\/a> API and widely used for traditional <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">RESTful web services<\/a>, like our library management APIs for example.<\/p>\n<pre class=\"brush:java\">@RestController\n@RequestMapping(\"\/library\")\npublic class LibraryController {\n    @Autowired private LibraryService libraryService;\n    \n    @RequestMapping(path = \"\/books\/{isbn}\", method = GET, produces = APPLICATION_JSON_VALUE)\n    public ResponseEntity&lt;Book&gt; findBook(@PathVariable String isbn) {\n        return libraryService\n            .findBook(isbn)\n            .map(ResponseEntity::ok)\n            .orElseGet(ResponseEntity.notFound()::build);\n    }\n    \n    @RequestMapping(path = \"\/books\", method = GET, produces = APPLICATION_JSON_VALUE)\n    public Collection&lt;Book&gt; getAll() {\n        return libraryService.getBooks();\n    }\n\n    @RequestMapping(path = \"\/books\", method = POST, consumes = APPLICATION_JSON_VALUE)\n    public ResponseEntity&lt;Book&gt; addBook(@RequestBody Book payload) {\n        final Book book = libraryService.addBook(payload);\n        \n        return ResponseEntity\n            .created(linkTo(methodOn(LibraryController.class).findBook(book.getIsbn())).toUri())\n            .body(book);\n    }\n}\n<\/pre>\n<p>It would be unfair not to mention a relatively new <a href=\"https:\/\/docs.spring.io\/spring\/docs\/current\/spring-framework-reference\/web-reactive.html\">Spring WebFlux<\/a> project, the counterpart of the <a href=\"https:\/\/docs.spring.io\/spring\/docs\/current\/spring-framework-reference\/web.html\">Spring Web MVC<\/a>, built on top of the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Reactive_programming\">reactive stack<\/a> and <a href=\"https:\/\/en.wikipedia.org\/wiki\/Asynchronous_I\/O\">non-blocking I\/O<\/a>.<\/p>\n<p>Innovative, productive and hugely successful, <a href=\"https:\/\/spring.io\/\">Spring Framework<\/a> is the number one choice for Java developers these days, particularly with respect to <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservice architecture<\/a>.<\/p>\n<h3><a name=\"spark\"><\/a>2.9. Spark Java<\/h3>\n<p><a href=\"http:\/\/sparkjava.com\/\">Spark<\/a>, also often referred as <a href=\"http:\/\/sparkjava.com\/\">Spark-Java<\/a> to eliminate the confusion with similarly named hyper-popular data processing framework, is a micro framework for creating web applications in Java with a minimal effort. It is heavily relying on its expressive and simple <a href=\"https:\/\/en.wikipedia.org\/wiki\/Domain-specific_language\">DSL<\/a>, designed by leveraging the power of <a href=\"https:\/\/www.oracle.com\/webfolder\/technetwork\/tutorials\/obe\/java\/Lambda-QuickStart\/index.html\">Java 8 lambda expressions<\/a>. It indeed leads to quite compact and clean code. For example, here is a sneak peak on our library management APIs definition:<\/p>\n<pre class=\"brush:java\">path(\"\/library\", () -&gt; {\n    get(\"\/books\", \n        (req, res) -&gt; libraryService.getBooks(),\n        json()\n    );\n            \n    get(\"\/books\/:isbn\", \n        (req, res) -&gt; libraryService\n            .findBook(req.params(\":isbn\"))\n            .orElseGet(() -&gt; {\n                res.status(404);\n                return null;\n            }), \n        json()\n    );\n            \n    post(\"\/books\", \n        (req, res) -&gt; libraryService\n            .addBook(JsonbBuilder.create().fromJson(req.body(), Book.class)),\n        json()\n    );\n});\n<\/pre>\n<p>Beside just Java, <a href=\"http:\/\/sparkjava.com\/\">Spark-Java<\/a> has first class <a href=\"https:\/\/kotlinlang.org\/\">Kotlin<\/a> support and although it is mainly used for creating <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">REST APIs<\/a>, it integrates with a multitude of template engines.<\/p>\n<h3><a name=\"restlet\"><\/a>2.10. Restlet<\/h3>\n<p><a href=\"https:\/\/restlet.com\/open-source\/\">Restlet<\/a> framework aims to help Java developers build better web APIs that follow <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">REST architectural style<\/a>. It provides pretty powerful routing and filtering capabilities along with offering numerous extensions. It has quite unique way to structure and bundle things together.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<pre class=\"brush:java\">public class BookResource extends ServerResource {\n    @Inject private LibraryService libraryService;\n    \n    @Get\n    public Book findBook() {\n        final String isbn = (String) getRequest().getAttributes().get(\"isbn\");\n        return libraryService.findBook(isbn).orElse(null);\n    }\n}\n\npublic class BooksResource extends ServerResource  {\n    @Inject private LibraryService libraryService;\n    \n    @Get\n    public Collection&lt;Book&gt; getAll() {\n        return libraryService.getBooks();\n    }\n    \n    @Post(\"json\")\n    public Representation addBook(Book payload) throws IOException {\n        return toRepresentation(libraryService.addBook(payload));\n    }\n}\n<\/pre>\n<p>And here are the bindings between the resources and their <a href=\"https:\/\/en.wikipedia.org\/wiki\/Uniform_Resource_Identifier\">URI<\/a>, basically the typical router.<\/p>\n<pre class=\"brush:java\">final Router router = new Router(getContext());\nrouter.attach(\"\/library\/books\/{isbn}\", BookResource.class);\nrouter.attach(\"\/library\/books\", BooksResource.class);\n<\/pre>\n<p>Interestingly, <a href=\"https:\/\/restlet.com\/open-source\/\">Restlet<\/a> is one of the few open-source frameworks which was able to grew up from a simple library to a <a href=\"https:\/\/restlet.com\/\">full-fledged RESTful APIs development platform<\/a>.<\/p>\n<h3><a name=\"vertx\"><\/a>2.11. Vert.x<\/h3>\n<p>The <a href=\"https:\/\/vertx.io\/\">Vert.x<\/a> project from <a href=\"http:\/\/www.eclipse.org\/\">Eclipse Foundation<\/a> is an open-source toolkit for building reactive applications on the JVM platform. It follows the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Reactive_programming\">reactive paradigm<\/a> and is designed from the ground up to be event-driven and non-blocking.<\/p>\n<p>It has tons of different components. One of them is <a href=\"https:\/\/vertx.io\/docs\/vertx-web\/java\/\">Vert.x-Web<\/a>, designated for writing sophisticated modern web applications and <a href=\"https:\/\/en.wikipedia.org\/wiki\/Hypertext_Transfer_Protocol\">HTTP<\/a>-based <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservices<\/a>. The snippet below showcases our library management web API implemented on top of <a href=\"https:\/\/vertx.io\/docs\/vertx-web\/java\/\">Vert.x-Web<\/a>.<\/p>\n<pre class=\"brush:java\">final LibraryService libraryService = ...;\n\nfinal Vertx vertx = Vertx.vertx();\nfinal HttpServer server = vertx.createHttpServer();\nfinal Router router = Router.router(vertx);\n        \nrouter\n    .get(\"\/library\/books\")\n    .produces(\"application\/json\")\n    .handler(context -&gt;\n        context\n            .response()\n            .putHeader(\"Content-Type\", \"application\/json\")\n            .end(Json.encodePrettily(libraryService.getBooks()))\n    );\n            \nrouter\n    .get(\"\/library\/books\/:isbn\")\n    .produces(\"application\/json\")\n    .handler(context -&gt;\n        libraryService\n            .findBook(context.request().getParam(\"isbn\"))\n            .ifPresentOrElse(\n                book -&gt; context\n                        .response()\n                        .putHeader(\"Content-Type\", \"application\/json\")\n                        .end(Json.encodePrettily(book)),\n                () -&gt; context\n                        .response()\n                        .setStatusCode(204)\n                        .putHeader(\"Content-Type\", \"application\/json\")\n                        .end()\n            )\n    );\n        \nrouter\n    .post(\"\/library\/books\")\n    .consumes(\"application\/json\")\n    .produces(\"application\/json\")\n    .handler(BodyHandler.create())\n    .handler(context -&gt; {\n        final Book book = libraryService\n            .addBook(context.getBodyAsJson().mapTo(Book.class));\n                \n        context\n            .response()\n            .putHeader(\"Content-Type\", \"application\/json\")\n            .end(Json.encodePrettily(book));\n    });\n        \nserver.requestHandler(router::accept);\nserver.listen(4567);\n<\/pre>\n<p>Some of the notable characteristics of the <a href=\"https:\/\/vertx.io\/\">Vert.x<\/a> are high performance and modular design. More to that, it is pretty lightweight, scales really well and natively supports Java, <a href=\"https:\/\/en.wikipedia.org\/wiki\/JavaScript\">JavaScript<\/a>, <a href=\"http:\/\/groovy-lang.org\/\">Groovy<\/a>, <a href=\"https:\/\/www.ruby-lang.org\/en\/\">Ruby<\/a>, <a href=\"https:\/\/ceylon-lang.org\/\">Ceylon<\/a>, <a href=\"https:\/\/www.scala-lang.org\/\">Scala<\/a> and <a href=\"https:\/\/kotlinlang.org\/\">Kotlin<\/a>.<\/p>\n<h3><a name=\"play\"><\/a>2.12. Play Framework<\/h3>\n<p><a href=\"https:\/\/www.playframework.com\/\">Play<\/a> is high velocity, hyper-productive web framework for Java and <a href=\"https:\/\/www.scala-lang.org\/\">Scala<\/a>. It is based on a lightweight, stateless, web-friendly architecture and is built on top of <a href=\"https:\/\/akka.io\/\">Akka Toolkit<\/a>. Although <a href=\"https:\/\/www.playframework.com\/\">Play<\/a> is full-fledged framework with exceptionally powerful templating engine, it is very well suited for <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">RESTful web services<\/a> development as well. Our library management web APIs could be easily designed in <a href=\"https:\/\/www.playframework.com\/\">Play<\/a>.<\/p>\n<pre class=\"brush:bash\">GET    \/library\/books           controllers.LibraryController.list\nGET    \/library\/books\/:isbn     controllers.LibraryController.show(isbn: String)\nPOST   \/library\/books           controllers.LibraryController.add\n<\/pre>\n<pre class=\"brush:java\">public class LibraryController extends Controller {\n    private LibraryService libraryService;\n\n    @Inject\n    public LibraryController(LibraryService libraryService) {\n        this.libraryService = libraryService;\n    }\n    \n    \n    public Result list() {\n        return ok(Json.toJson(libraryService.getBooks()));\n    }\n\n    public Result show(String isbn) {\n        return  libraryService\n            .findBook(isbn)\n            .map(resource -&gt; ok(Json.toJson(resource)))\n            .orElseGet(() -&gt; notFound());\n    }\n    \n    public Result add() {\n        JsonNode json = request().body().asJson();\n        final Book book = Json.fromJson(json, Book.class);\n        return created(Json.toJson(libraryService.addBook(book)));\n    }\n}\n<\/pre>\n<p>The ability of <a href=\"https:\/\/www.playframework.com\/\">Play<\/a> to serve both backend (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">RESTful<\/a>) and frontend (using for example <a href=\"https:\/\/angular.io\/\">Angular<\/a>, <a href=\"https:\/\/reactjs.org\/\">React<\/a>, <a href=\"https:\/\/vuejs.org\/\">Vue.js<\/a>) endpoints, in other words going full-stack, &nbsp;might be an attractive offering with respect to implementing <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservices<\/a> using a single framework (although such decisions should be taken with a great care).<\/p>\n<h3><a name=\"akkahttp\"><\/a>2.13. Akka HTTP<\/h3>\n<p><a href=\"https:\/\/akka.io\/akka-http\/\">Akka HTTP<\/a>, the part of amazing <a href=\"https:\/\/akka.io\/\">Akka Toolkit<\/a> family, provides a full server-side and client-side <a href=\"https:\/\/en.wikipedia.org\/wiki\/Hypertext_Transfer_Protocol\">HTTP<\/a> stack implemented on top of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Actor_model\">actor model<\/a>. It\u2019s not a full-fledged web framework (like <a href=\"https:\/\/www.playframework.com\/\">Play<\/a>, for example) but crafted specifically to manage <a href=\"https:\/\/en.wikipedia.org\/wiki\/Hypertext_Transfer_Protocol\">HTTP<\/a>-based services. Similarly to other frameworks, <a href=\"https:\/\/akka.io\/akka-http\/\">Akka HTTP<\/a> has own <a href=\"https:\/\/doc.akka.io\/docs\/akka-http\/current\/routing-dsl\/index.html\">DSL<\/a> to elegantly define <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">RESTful web API<\/a> endpoints. The best way to give it a try is to create our library management API definitions.<\/p>\n<pre class=\"brush:java\">public class LibraryRoutes extends AllDirectives {\n    private final LibraryService libraryService;\n\n    \/\/ ...    \n    \n    public Route routes() {\n        return route(\n            pathPrefix(\"library\", () -&gt;\n                pathPrefix(\"books\", () -&gt;\n                    route(\n                        pathEndOrSingleSlash(() -&gt;\n                            route(\n                                get(() -&gt;\n                                    complete(StatusCodes.OK, libraryService.getBooks(), Jackson.marshaller())\n                                ),\n                                post(() -&gt;\n                                    entity(\n                                        Jackson.unmarshaller(Book.class),\n                                        payload -&gt; complete(StatusCodes.OK, libraryService.addBook(payload), Jackson.marshaller())\n                                    )\n                                )\n                            )\n                        ),\n                        path(PathMatchers.segment(), isbn -&gt; \n                            route(\n                                get(() -&gt; \n                                    libraryService\n                                        .findBook(isbn)\n                                        .map(book -&gt; (Route)complete(StatusCodes.OK, book, Jackson.marshaller()))\n                                        .orElseGet(() -&gt; complete(StatusCodes.NOT_FOUND))\n                                )\n                            )\n                        )\n                    )\n                )\n            )\n        );\n    }\n}\n<\/pre>\n<p><a href=\"https:\/\/akka.io\/akka-http\/\">Akka HTTP<\/a> has first-class support of Java and <a href=\"https:\/\/www.scala-lang.org\/\">Scala<\/a> and is an excellent choice for building <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">RESTful web services<\/a> and scalable <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservice architecture<\/a> in general.<\/p>\n<h3><a name=\"micronaut\"><\/a>2.14. Micronaut<\/h3>\n<p><a href=\"http:\/\/micronaut.io\/\">Micronaut<\/a> is a modern, JVM-based, full-stack framework for building modular, easily testable microservice applications. It is truly polyglot (in JVM sense) and offers support for Java, <a href=\"http:\/\/groovy-lang.org\/\">Groovy<\/a>, and <a href=\"https:\/\/kotlinlang.org\/\">Kotlin<\/a> out of the box.<\/p>\n<p><a href=\"http:\/\/micronaut.io\/\">Micronaut<\/a>\u2019s focus is a first-class support of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Reactive_programming\">reactive programming<\/a> paradigm and compile-time dependency injection. Here is the skeleton of our library management web APIs declaration in <a href=\"http:\/\/micronaut.io\/\">Micronaut<\/a>.<\/p>\n<pre class=\"brush:java\">@Controller(\"\/library\")\npublic class LibraryController {\n    @Inject private LibraryService libraryService;\n    \n    @Get(\"\/books\/{isbn}\")\n    @Produces(MediaType.APPLICATION_JSON)\n    public Optional&lt;Book&gt; findBook(String isbn) {\n        return libraryService.findBook(isbn);\n    }\n    \n    @Get(\"\/books\")\n    @Produces(MediaType.APPLICATION_JSON)\n    public Observable&lt;Book&gt; getAll() {\n        return Observable.fromIterable(libraryService.getBooks());\n    }\n    \n    @Post(\"\/books\")\n    @Consumes(MediaType.APPLICATION_JSON)\n    public HttpResponse&lt;Book&gt; addBook(Book payload) {\n        return HttpResponse.created(libraryService.addBook(payload));\n    }\n}\n<\/pre>\n<p>Comparing to others, <a href=\"http:\/\/micronaut.io\/\">Micronaut<\/a> is very young but promising framework, focused on modern programming. It is a fresh start without the baggage accumulated over the years.<\/p>\n<h2><a name=\"graphql\"><\/a>3. GraphQL, the New Force<\/h2>\n<p>The popularity of the <a href=\"http:\/\/facebook.github.io\/graphql\/\">GraphQL<\/a> is slowly but steadily growing. It has proven to be an indispensable tool to address a wide range of the problems although there are not many choices available for Java developers. Along this section we are going to use the same <a href=\"http:\/\/facebook.github.io\/graphql\/\">GraphQL<\/a> schema we have discussed in <a href=\"https:\/\/www.javacodegeeks.com\/2018\/08\/microservices-java-developers-microservices-communication.html#graphql\">the previous part of the tutorial<\/a>, repeated below just for convenience.<\/p>\n<pre class=\"brush:bash\">schema {\n  query: Query\n  mutation: Mutation\n}\n\ntype Book {\n  isbn: ID!\n  title: String!\n  year: Int\n}\n\ntype Query {\n  books: [Book]\n  book(isbn: ID!): Book\n}\n\ntype Mutation {\n  addBook(isbn: ID!, title: String!, year: Int): Book\n  updateBook(isbn: ID!, title: String, year: Int): Book\n  removeBook(isbn: ID!): Boolean\n}\n<\/pre>\n<p>[ulp id=&#8217;DdINgEqoOovgkhhk&#8217;]<br \/>\n&nbsp;<\/p>\n<h3><a name=\"sangria\"><\/a>3.1. Sangria<\/h3>\n<p><a href=\"https:\/\/sangria-graphql.org\/\">Sangria<\/a> is the <a href=\"http:\/\/facebook.github.io\/graphql\/\">GraphQL<\/a> implementation in <a href=\"https:\/\/www.scala-lang.org\/\">Scala<\/a>. This is a terrific framework with a vibrant community and seamless integration with <a href=\"https:\/\/sangria-graphql.org\/getting-started\/#akka-http-graphql-endpoint\">Akka HTTP<\/a> and\/or <a href=\"https:\/\/sangria-graphql.org\/getting-started\/#play-graphql-endpoint\">Play Framework<\/a>. Although it does not provide Java-friendly APIs at the moment, it is worth mentioning nonetheless. It takes a bit different approach by defining the schema along the resolvers in the code, for example.<\/p>\n<pre class=\"brush:scala\">object SchemaDefinition {\n  val BookType = ObjectType(\n    \"Book\", \"A book.\", fields[LibraryService, Book](\n      Field(\"isbn\", StringType, Some(\"The book's ISBN.\"), resolve = _.value.isbn),\n      Field(\"title\", StringType, Some(\"The book's title.\"), resolve = _.value.title),\n      Field(\"year\", IntType, Some(\"The book's year.\"), resolve = _.value.year)\n    ))\n    \n  val ISBN = Argument(\"isbn\", StringType, description = \"ISBN\")\n  val Title = Argument(\"title\", StringType, description = \"Book's title\")\n  val Year = Argument(\"year\", IntType, description = \"Book's year\")\n\n  val Query = ObjectType(\n    \"Query\", fields[LibraryService, Unit](\n      Field(\"book\", OptionType(BookType),\n        arguments = ISBN :: Nil,\n        resolve = ctx \u21d2 ctx.ctx.findBook(ctx arg ISBN)),\n      Field(\"books\", ListType(BookType),\n        resolve = ctx \u21d2  ctx.ctx.getBooks())\n    ))\n\n  val Mutation = ObjectType(\n    \"Mutation\", fields[LibraryService, Unit](\n      Field(\"addBook\", BookType,\n        arguments = ISBN :: Title :: Year :: Nil,\n        resolve = ctx \u21d2 ctx.ctx.addBook(Book(ctx arg ISBN, ctx arg Title, ctx arg Year))),\n      Field(\"updateBook\", BookType,\n        arguments = ISBN :: Title :: Year :: Nil,\n        resolve = ctx \u21d2 ctx.ctx.updateBook(ctx arg ISBN, Book(ctx arg ISBN, ctx arg Title, ctx arg Year))),\n      Field(\"removeBook\", BooleanType,\n        arguments = ISBN :: Nil,\n        resolve = ctx \u21d2 ctx.ctx.removeBook(ctx arg ISBN))\n    ))\n    \n   val LibrarySchema = Schema(Query, Some(Mutation))\n}\n<\/pre>\n<p>Although there are some pros and cons to the code-first schema development, it may be a good solution in certain <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservice architecture<\/a> implementations.<\/p>\n<h3><a name=\"javagraphql\"><\/a>3.2. graphql-java<\/h3>\n<p>Easy to guess, <a href=\"https:\/\/github.com\/graphql-java\/graphql-java\">graphql-java<\/a> is the <a href=\"http:\/\/facebook.github.io\/graphql\/\">GraphQL<\/a> implementation in Java. It has pretty good integration with <a href=\"https:\/\/github.com\/graphql-java\/graphql-spring-boot\">Spring Framework<\/a> as well as any other <a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=369\">Servlet<\/a>-compatible framework or container. In the case of such a simple <a href=\"http:\/\/facebook.github.io\/graphql\/\">GraphQL<\/a> schema as ours, the implementation is just a matter of defining resolvers.<\/p>\n<pre class=\"brush:java\">public class Query implements GraphQLQueryResolver {\n    private final LibraryService libraryService;\n    \n    public Query(final LibraryService libraryService) {\n        this.libraryService = libraryService;\n    }\n    \n    public Optional&lt;Book&gt; book(String isbn) {\n        return libraryService.findBook(isbn);\n    }\n    \n    public List&lt;Book&gt; books() {\n        return new ArrayList&lt;&gt;(libraryService.getBooks());\n    }\n}\n\n<\/pre>\n<pre class=\"brush:java\">public class Mutation implements GraphQLMutationResolver {\n    private final LibraryService libraryService;\n    \n    public Mutation(final LibraryService libraryService) {\n        this.libraryService = libraryService;\n    }\n        \n    public Book addBook(String isbn, String title, int year) {\n        return libraryService.addBook(new Book(isbn, title, year));\n    }\n    \n    public Book updateBook(String isbn, String title, int year) {\n        return libraryService.updateBook(isbn, new Book(isbn, title, year));\n    }\n    \n    public boolean removeBook(String isbn) {\n        return libraryService.removeBook(isbn);\n    }\n}\n<\/pre>\n<p>And this is literally it. If you are considering using <a href=\"http:\/\/facebook.github.io\/graphql\/\">GraphQL<\/a> in some or across all services in your <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservice architecture<\/a>, the <a href=\"https:\/\/github.com\/graphql-java\/graphql-java\">graphql-java<\/a> could be a robust foundation to build upon.<\/p>\n<h2><a name=\"rpc\"><\/a>4. The RPC Style<\/h2>\n<p>Comparing to <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">RESTful<\/a> or <a href=\"http:\/\/facebook.github.io\/graphql\/\">GraphQL<\/a>, the efficiency of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Remote_procedure_call\">RPC<\/a> conversations, specifically for service-to-service communication, is really hard to beat. The <a href=\"https:\/\/grpc.io\/\">gRPC<\/a> framework from <a href=\"https:\/\/www.google.com\">Google<\/a> is taking a lead here but this is not the only player.<\/p>\n<p>As we are going to see, many <a href=\"https:\/\/en.wikipedia.org\/wiki\/Remote_procedure_call\">RPC<\/a> systems are built on the idea of defining a service contract: in Java it is typically an annotated interface definition. The server side implements this interface and exposes it over the wire, whereas on the client side this interface is used to get a proxy or a stub.<\/p>\n<h3><a name=\"javagrpc\"><\/a>4.1. java-grpc<\/h3>\n<p>We have briefly glanced through <a href=\"https:\/\/grpc.io\/\">gRPC<\/a> generic concepts in the <a href=\"https:\/\/www.javacodegeeks.com\/2018\/08\/microservices-java-developers-microservices-communication.html#grpc\">previous part of the tutorial<\/a>, but in this section we are going to talk about its Java implementation &#8211; <a href=\"https:\/\/github.com\/grpc\/grpc-java\">java-grpc<\/a>. Since mostly everything is generated for you from the <a href=\"https:\/\/developers.google.com\/protocol-buffers\/\">Protocol Buffers<\/a> service definition, the only thing left to the developers is to provide the relevant service implementations. Here is the <a href=\"https:\/\/grpc.io\/\">gRPC<\/a> version of our library management service.<\/p>\n<pre class=\"brush:java\">static class LibraryImpl extends LibraryGrpc.LibraryImplBase {\n    private final LibraryService libraryService;\n        \n    public LibraryImpl(final LibraryService libraryService) {\n        this.libraryService = libraryService;\n    }\n        \n    @Override\n    public void addBook(AddBookRequest request, StreamObserver&lt;Book&gt; responseObserver) {\n        final Book book = Book.newBuilder()\n            .setIsbn(request.getIsbn())\n            .setTitle(request.getTitle())\n            .setYear(request.getYear())\n            .build();\n\n        responseObserver.onNext(libraryService.addBook(book));\n        responseObserver.onCompleted();\n    }\n        \n    @Override\n    public void getBooks(Filter request, StreamObserver&lt;BookList&gt; responseObserver) {\n        final BookList bookList = BookList\n            .newBuilder()\n            .addAllBooks(libraryService.getBooks())\n            .build();\n        responseObserver.onNext(bookList);\n        responseObserver.onCompleted();\n    }\n        \n    @Override\n    public void updateBook(UpdateBookRequest request, StreamObserver&lt;Book&gt; responseObserver) {\n        responseObserver.onNext(libraryService.updateBook(request.getIsbn(), request.getBook()));\n        responseObserver.onCompleted();\n    }\n        \n    @Override\n    public void removeBook(RemoveBookRequest request, StreamObserver&lt;Empty&gt; responseObserver) {\n        libraryService.removeBook(request.getIsbn());\n        responseObserver.onCompleted();\n    }\n}\n<\/pre>\n<p>It is worth mentioning that <a href=\"https:\/\/developers.google.com\/protocol-buffers\/\">Protocol Buffers<\/a> is the default but not the only serialization mechanism, <a href=\"https:\/\/grpc.io\/\">gRPC<\/a> could be used <a href=\"https:\/\/grpc.io\/blog\/grpc-with-json\">with JSON encoding<\/a> as well. By and large, <a href=\"https:\/\/grpc.io\/\">gRPC<\/a> works amazingly well, and is certainly a safe bet with respect to implementing service-to-service communication in the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservice architecture<\/a>. But more to come, stay tuned, <a href=\"https:\/\/github.com\/grpc\/grpc-web\">grpc-web<\/a> is around the corner.<\/p>\n<h3><a name=\"reactivegrpc\"><\/a>4.2. Reactive gRPC<\/h3>\n<p>In the recent years <a href=\"https:\/\/en.wikipedia.org\/wiki\/Reactive_programming\">reactive programming<\/a> is steadily making its way to the mainstream. The <a href=\"https:\/\/github.com\/salesforce\/reactive-grpc\">Reactive gRPC<\/a> is a suite of libraries to augment <a href=\"https:\/\/grpc.io\/\">gRPC<\/a> to work with <a href=\"http:\/\/www.reactive-streams.org\/\">Reactive Streams<\/a> implementations. In the nutshell, it just generates alternative <a href=\"https:\/\/grpc.io\/\">gRPC<\/a> bindings, with respect to the library of your choice (<a href=\"https:\/\/github.com\/salesforce\/reactive-grpc\/tree\/master\/rx-java\">RxJava 2<\/a> and&nbsp; <a href=\"https:\/\/github.com\/salesforce\/reactive-grpc\/tree\/master\/reactor\">Spring Reactor<\/a> as of now), everything else stays pretty much unchanged. To prove it, let us take a look on the <code>LibraryImpl<\/code> implementation using <a href=\"http:\/\/www.reactive-streams.org\/\">Reactive Streams<\/a> APIs.<\/p>\n<pre class=\"brush:java\">static class LibraryImpl extends RxLibraryGrpc.LibraryImplBase {\n    private final LibraryService libraryService;\n        \n    public LibraryImpl(final LibraryService libraryService) {\n        this.libraryService = libraryService;\n    }\n        \n    @Override\n    public Single&lt;Book&gt; addBook(Single&lt;AddBookRequest&gt; request) {\n        return request\n            .map(r -&gt; \n                Book\n                    .newBuilder()\n                    .setIsbn(r.getIsbn())\n                    .setTitle(r.getTitle())\n                    .setYear(r.getYear())\n                    .build())\n            .map(libraryService::addBook);\n    }\n        \n    @Override\n    public Single&lt;BookList&gt; getBooks(Single&lt;Filter&gt; request) {\n        return request\n            .map(r -&gt; \n                BookList\n                    .newBuilder()\n                    .addAllBooks(libraryService.getBooks())\n                    .build());\n    }\n        \n    @Override\n    public Single&lt;Book&gt; updateBook(Single&lt;UpdateBookRequest&gt; request) {\n        return request\n            .map(r -&gt; libraryService.updateBook(r.getIsbn(), r.getBook()));\n    }\n        \n    @Override\n    public Single&lt;Empty&gt; removeBook(Single&lt;RemoveBookRequest&gt; request) {\n        return request\n            .map(r -&gt; {\n                libraryService.removeBook(r.getIsbn());\n                return Empty.newBuilder().build();\n            });\n    }\n}\n<\/pre>\n<p>To be fair, <a href=\"https:\/\/github.com\/salesforce\/reactive-grpc\">Reactive gRPC<\/a> is not the full-fledged <a href=\"https:\/\/grpc.io\/\">gRPC<\/a> implementation but rather an excellent addition to the <a href=\"https:\/\/github.com\/grpc\/grpc-java\">java-grpc<\/a>.<\/p>\n<h3><a name=\"akkagrpc\"><\/a>4.3. Akka gRPC<\/h3>\n<p>Yet another great tool from <a href=\"https:\/\/akka.io\/\">Akka Toolkit<\/a> box, <a href=\"https:\/\/github.com\/akka\/akka-grpc\">Akka gRPC<\/a> provides support for building streaming <a href=\"https:\/\/grpc.io\/\">gRPC<\/a> servers and clients on top of <a href=\"https:\/\/doc.akka.io\/docs\/akka\/current\/stream\/index.html\">Akka Streams<\/a> (and <a href=\"https:\/\/akka.io\/\">Akka Toolkit<\/a> in general). The Java-based implementation is relying on <code>CompletionStage<\/code> from the standard library and is quite straightforward to use.<\/p>\n<pre class=\"brush:java\">public class LibraryImpl implements Library {\n    private final LibraryService libraryService;\n    \n    public LibraryImpl(final LibraryService libraryService) {\n        this.libraryService = libraryService;\n    }\n    \n    @Override\n    public CompletionStage&lt;Book&gt; addBook(AddBookRequest in) {\n        final Book book = Book\n            .newBuilder()\n            .setIsbn(in.getIsbn())\n            .setTitle(in.getTitle())\n            .setYear(in.getYear())\n            .build();\n        \n        return CompletableFuture.completedFuture(libraryService.addBook(book));\n    }\n\n    @Override\n    public CompletionStage&lt;BookList&gt; getBooks(Filter in) {\n        return CompletableFuture.completedFuture(\n            BookList\n                .newBuilder()\n                .addAllBooks(libraryService.getBooks())\n                .build());\n    }\n    \n    @Override\n    public CompletionStage&lt;Book&gt; updateBook(UpdateBookRequest in) {\n        return CompletableFuture.completedFuture(libraryService.updateBook(in.getIsbn(), in.getBook()));\n    }\n    \n    @Override\n    public CompletionStage&lt;Empty&gt; removeBook(RemoveBookRequest in) {\n        libraryService.removeBook(in.getIsbn());\n        return CompletableFuture.completedFuture(Empty.newBuilder().build());\n    }\n}\n<\/pre>\n<p><a href=\"https:\/\/github.com\/akka\/akka-grpc\">Akka gRPC<\/a> is quite a new member of the <a href=\"https:\/\/akka.io\/\">Akka Toolkit<\/a> and is currently in the preview mode. It could be used already today but certainly expect some changes in the future.<\/p>\n<h3><a name=\"bubbo\"><\/a>4.4. Apache Dubbo<\/h3>\n<p><a href=\"https:\/\/github.com\/apache\/incubator-dubbo\">Apache Dubbo<\/a>, currently under the incubation within <a href=\"https:\/\/www.apache.org\/\">Apache Software Foundation<\/a> but initially developed at <a href=\"http:\/\/www.alibaba.com\">Alibaba<\/a>, is a high-performance, Java-based, open source <a href=\"https:\/\/en.wikipedia.org\/wiki\/Remote_procedure_call\">RPC<\/a> framework. Our library service could be up and running just in a few lines of code.<\/p>\n<pre class=\"brush:java\">final ServiceConfig serviceConfig = new ServiceConfig();\nserviceConfig.setApplication(new ApplicationConfig(\"library-provider\"));\nserviceConfig.setRegistry(new RegistryConfig(\"multicast:\/\/224.5.6.7:1234\"));\nserviceConfig.setInterface(LibraryService.class);\nserviceConfig.setRef(new LibraryServiceImpl());\nserviceConfig.export();\n<\/pre>\n<p>It is purely Java-oriented so if you are aiming to build the polyglot <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservice architecture<\/a>, <a href=\"https:\/\/github.com\/apache\/incubator-dubbo\">Apache Dubbo<\/a> might not help you there natively but through additional integrations, like for example <a href=\"https:\/\/github.com\/dubbo\/dubbo-samples\/tree\/master\/dubbo-samples-rest\">RPC over REST<\/a> or <a href=\"https:\/\/github.com\/dubbo\/dubbo-samples\/tree\/master\/dubbo-samples-http\">RPC over HTTP<\/a>.<\/p>\n<h3><a name=\"finagle\"><\/a>4.5. Finatra and Finagle<\/h3>\n<p><a href=\"https:\/\/twitter.github.io\/finagle\/guide\/index.html\">Finagle<\/a>, the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Remote_procedure_call\">RPC<\/a> library, and <a href=\"https:\/\/twitter.github.io\/finatra\/\">Finatra<\/a>, the services framework built on top of it, were born at <a href=\"https:\/\/twitter.github.io\/\">Twitter<\/a> and open-sourced shortly after.<\/p>\n<blockquote>\n<p><a href=\"https:\/\/twitter.github.io\/finagle\/guide\/index.html\"><em>Finagle<\/em><\/a> <em>is an extensible RPC system for the JVM, used to construct high-concurrency servers. Finagle implements uniform client and server APIs for several protocols, and is designed for high performance and concurrency. &#8211; <\/em><a href=\"https:\/\/github.com\/twitter\/finagle\"><em>https:\/\/github.com\/twitter\/finagle<\/em><\/a><\/p>\n<p><a href=\"https:\/\/twitter.github.io\/finatra\/\"><em>Finatra<\/em><\/a> <em>is a lightweight framework for building fast, testable, scala applications on top of <\/em><a href=\"https:\/\/github.com\/twitter\/twitter-server\"><em>TwitterServer<\/em><\/a><em> and <\/em><a href=\"https:\/\/github.com\/twitter\/finagle\"><em>Finagle<\/em><\/a><em>.<\/em> &#8211; <a href=\"https:\/\/github.com\/twitter\/finatra\">https:\/\/github.com\/twitter\/finatra<\/a><\/p>\n<\/blockquote>\n<p>They are both <a href=\"https:\/\/www.scala-lang.org\/\">Scala<\/a>-based and are actively used in production. <a href=\"https:\/\/twitter.github.io\/finagle\/guide\/index.html\">Finagle<\/a> was one of the first libraries to use <a href=\"https:\/\/thrift.apache.org\/\">Apache Thrift<\/a> for service generation and binary serialization. Let us grab the library service <a href=\"https:\/\/en.wikipedia.org\/wiki\/Interface_description_language\">IDL<\/a> from the <a href=\"https:\/\/www.javacodegeeks.com\/2018\/08\/microservices-java-developers-microservices-communication.html#thrift\">previous part of the tutorial<\/a> and implement it as a <a href=\"https:\/\/twitter.github.io\/finatra\/\">Finatra<\/a> service (as usual, most of the scaffolding code is generated on our behalf).<\/p>\n<pre class=\"brush:scala\">@Singleton\nclass LibraryController @Inject()(libraryService: LibraryService) extends Controller with Library.BaseServiceIface {\n  override val addBook = handle(AddBook) { args: AddBook.Args =&gt;\n    Future.value(libraryService.addBook(args.book))\n  }\n  \n  override val getBooks = handle(GetBooks) { args: GetBooks.Args =&gt;\n    Future.value(libraryService.getBooks())\n  }\n  \n  override val removeBook = handle(RemoveBook) { args: RemoveBook.Args =&gt;\n    Future.value(libraryService.removeBook(args.isbn))\n  }\n  \n  override val updateBook = handle(UpdateBook) { args: UpdateBook.Args =&gt;\n    Future.value(libraryService.updateBook(args.isbn, args.book))\n  }\n}\n<\/pre>\n<p>One of the distinguishing features of the <a href=\"https:\/\/twitter.github.io\/finagle\/guide\/index.html\">Finagle<\/a> is the out of the box support of distributed tracing and statistics for monitoring and diagnostics, invaluable insights for operating the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservices<\/a> in production.<\/p>\n<h2><a name=\"messaging\"><\/a>5. Messaging and Eventing<\/h2>\n<p>In <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservice architecture<\/a>, and generally in many loosely coupled distributed systems, some form of message and event passing is one of the basic building blocks. Along this section we are going to talk about few frameworks and outline a number of messaging solutions you may use independently of the framework of your choice.<\/p>\n<h3><a name=\"axon\"><\/a>5.1. Axon Framework<\/h3>\n<p><a href=\"https:\/\/axoniq.io\/\">Axon<\/a> is a lightweight, open-source Java framework to build scalable, extensible event-driven applications. It is one of the pioneers to employ the sound architectural principles of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Domain-driven_design\">domain-driven design<\/a> (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Domain-driven_design\">DDD<\/a>) and <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/architecture\/patterns\/cqrs\">Command and Query Responsibility Segregation<\/a> (<a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/architecture\/patterns\/cqrs\">CQRS<\/a>) in practice.<\/p>\n<h3><a name=\"lagom\"><\/a>5.2. Lagom<\/h3>\n<p><a href=\"https:\/\/www.lightbend.com\/lagom-framework\">Lagom<\/a> is an opinionated, open source framework for building reactive microservice systems in Java or <a href=\"https:\/\/www.scala-lang.org\/\">Scala<\/a>. <a href=\"https:\/\/www.lightbend.com\/lagom-framework\">Lagom<\/a> stands on the shoulders of giants, <a href=\"https:\/\/akka.io\/\">Akka Toolkit<\/a> and <a href=\"https:\/\/www.playframework.com\/\">Play! Framework<\/a>, two proven technologies that are battle-tested in production in many of the most demanding applications. Its designed after the principles of the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Domain-driven_design\">domain-driven design<\/a> (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Domain-driven_design\">DDD<\/a>), <a href=\"https:\/\/martinfowler.com\/eaaDev\/EventSourcing.html\">Event Sourcing<\/a> and <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/architecture\/patterns\/cqrs\">Command and Query Responsibility Segregation<\/a> (<a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/architecture\/patterns\/cqrs\">CQRS<\/a>) and strongly encourages usage of these patterns.<\/p>\n<h3><a name=\"akka\"><\/a>5.3. Akka<\/h3>\n<p><a href=\"https:\/\/akka.io\/\">Akka<\/a> is a toolkit for building highly concurrent, distributed, and resilient message-driven applications for Java and <a href=\"https:\/\/www.scala-lang.org\/\">Scala<\/a>. As we have seen, <a href=\"https:\/\/akka.io\/\">Akka<\/a> serves as a foundation for a several other high-level frameworks (like for example <a href=\"#_Akka_HTTP\">Akka HTTP<\/a> and <a href=\"#_Play_Framework\">Play Framework<\/a>), however it is by itself is a great way to build <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservices<\/a> which could be decomposed into independent <a href=\"https:\/\/en.wikipedia.org\/wiki\/Actor_model\">actors<\/a>. The library management actor is an example of such a solution.<\/p>\n<pre class=\"brush:java\">public class LibraryActor extends AbstractActor {\n    private final LibraryService libraryService;\n    \n    public LibraryActor(final LibraryService libraryService) {\n        this.libraryService = libraryService;\n    }\n    \n    @Override\n    public Receive createReceive() {\n        return receiveBuilder()\n            .match(GetBooks.class, e -&gt; \n                getSender().tell(libraryService.getBooks(), self()))\n            .match(AddBook.class, e -&gt; { \n                final Book book = new Book(e.getIsbn(), e.getTitle());\n                getSender().tell(libraryService.addBook(book), self());\n            })\n            .match(FindBook.class, e -&gt; \n                getSender().tell(libraryService.findBook(e.getIsbn()), self()))\n            .matchAny(o -&gt; log.info(\"received unknown message\"))\n            .build();\n    }\n}\n<\/pre>\n<p>Communication between <a href=\"https:\/\/akka.io\/\">Akka<\/a> actors is very efficient and is not based on <a href=\"https:\/\/en.wikipedia.org\/wiki\/Hypertext_Transfer_Protocol\">HTTP<\/a> protocol (one of the preferred transports is <a href=\"https:\/\/github.com\/real-logic\/aeron\">Aeron<\/a>, which we have briefly talked about <a href=\"https:\/\/www.javacodegeeks.com\/2018\/08\/microservices-java-developers-microservices-communication.html#aeron\">in the previous part of the tutorial<\/a>). The <a href=\"https:\/\/doc.akka.io\/docs\/akka\/current\/persistence.html?language=java\">Akka Persistence<\/a> module enables stateful actors to persist their internal state and recover it later. There are certain complexities you may run into while implementing <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservice architecture<\/a> using <a href=\"https:\/\/akka.io\/\">Akka<\/a> but overall it is a solid and trusted choice.<\/p>\n<h3><a name=\"zeromq\"><\/a>5.4. ZeroMQ<\/h3>\n<p><a href=\"http:\/\/zeromq.org\/\">ZeroMQ<\/a> is not a typical messaging middleware. It is completely brokerless (originally the <strong>zero<\/strong> prefix in <a href=\"http:\/\/zeromq.org\/\">ZeroMQ<\/a> was meant as &#8220;zero broker&#8221;).<\/p>\n<blockquote>\n<p><a href=\"http:\/\/zeromq.org\/\"><em>ZeroMQ<\/em><\/a><em> (also known as \u00d8MQ, 0MQ, or zmq) looks like an embeddable networking library but acts like a concurrency framework. It gives you sockets that carry atomic messages across various transports like in-process, inter-process, TCP, and multicast. You can connect sockets N-to-N with patterns like fan-out, pub-sub, task distribution, and request-reply. It&#8217;s fast enough to be the fabric for clustered products. Its asynchronous I\/O model gives you scalable multicore applications, built as asynchronous message-processing tasks. It has a score of language APIs and runs on most operating systems. &#8211; <\/em><a href=\"http:\/\/zguide.zeromq.org\/page:all#ZeroMQ-in-a-Hundred-Words\"><em>http:\/\/zguide.zeromq.org\/page:all#ZeroMQ-in-a-Hundred-Words<\/em><\/a><\/p>\n<\/blockquote>\n<p>It is widely used in the applications and services where achieving the low latency is a must. Those are the spots in <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservice architecture<\/a> where <a href=\"http:\/\/zeromq.org\/\">ZeroMQ<\/a> might be of great help.<\/p>\n<h3><a name=\"kafka\"><\/a>5.5. Apache Kafka<\/h3>\n<p><a href=\"http:\/\/kafka.apache.org\/\">Apache Kafka<\/a>, started from the idea of <a href=\"https:\/\/engineering.linkedin.com\/distributed-systems\/log-what-every-software-engineer-should-know-about-real-time-datas-unifying\">building the distributed log system<\/a>, has expanded way beyond that into a distributed streaming platform. It is horizontally scalable, fault-tolerant, wicked fast, and is able to digest insanely massive volumes of messages (or events).<\/p>\n<p>The hyper-popularity of the <a href=\"http:\/\/kafka.apache.org\/\">Apache Kafka<\/a> (and for good reasons) had an effect that many other message brokers became forgotten and undeservedly are fading away. It is highly unlikely that <a href=\"http:\/\/kafka.apache.org\/\">Apache Kafka<\/a> will not be able to keep up with the demand of your <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservice architecture<\/a> implementation, but more often than not a simpler alternative could be an answer.<\/p>\n<h3><a name=\"rabbitmq\"><\/a>5.6. RabbitMQ and Apache Qpid<\/h3>\n<p><a href=\"https:\/\/www.rabbitmq.com\">RabbitMQ<\/a> and <a href=\"https:\/\/qpid.apache.org\/\">Apache Qpid<\/a> are classical examples of the message brokers which speak <a href=\"https:\/\/en.wikipedia.org\/wiki\/Advanced_Message_Queuing_Protocol\">AMQP<\/a> protocol. Not much to say beside that <a href=\"https:\/\/www.rabbitmq.com\">RabbitMQ<\/a> is most known for the fact it is written in <a href=\"https:\/\/www.erlang.org\/\">Erlang<\/a>. Both are open source and good choices to serve as the messaging backbone between your <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservices<\/a>.<\/p>\n<h3><a name=\"activemq\"><\/a>5.7. Apache ActiveMQ<\/h3>\n<p><a href=\"http:\/\/activemq.apache.org\/\">Apache ActiveMQ<\/a> is one of the oldest and most powerful open source messaging solutions out there. It supports a wide range of the protocols (including <a href=\"https:\/\/en.wikipedia.org\/wiki\/Advanced_Message_Queuing_Protocol\">AMQP<\/a>, <a href=\"https:\/\/stomp.github.io\/\">STOMP<\/a>, <a href=\"http:\/\/mqtt.org\/\">MQTT<\/a>) while being fully compliant with <a href=\"http:\/\/www.oracle.com\/technetwork\/java\/jms\/index.html\">Java Messaging Service<\/a> (<a href=\"http:\/\/java.sun.com\/products\/jms\/\">JMS 1.1<\/a>) specification.<\/p>\n<p>Interestingly, there are quite a few different message brokers hidden under <a href=\"http:\/\/activemq.apache.org\/\">Apache ActiveMQ<\/a> umbrella. One of those is <a href=\"https:\/\/activemq.apache.org\/artemis\/\">ActiveMQ Artemis<\/a> with a goal to be a multi-protocol, embeddable, very high performance, clustered, asynchronous messaging system.<\/p>\n<p>Another one is <a href=\"http:\/\/activemq.apache.org\/apollo\/\">ActiveMQ Apollo<\/a>, a development effort to come up with a faster, more reliable and easier to maintain messaging broker. It was built from the foundations of the original <a href=\"http:\/\/activemq.apache.org\/\">Apache ActiveMQ<\/a> with radically different threading and message dispatching architecture. Although very promising, it seems to be abandoned.<\/p>\n<p>It is very likely that <a href=\"http:\/\/activemq.apache.org\/\">Apache ActiveMQ<\/a> has every feature you need in order for your <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservices<\/a> to communicate the messages reliably. Also, the <a href=\"http:\/\/java.sun.com\/products\/jms\/\">JMS<\/a> support might be an important benefit in the enterprise world.<\/p>\n<h3><a name=\"rocketmq\"><\/a>5.8. Apache RocketMQ<\/h3>\n<p><a href=\"https:\/\/rocketmq.apache.org\/\">Apache RocketMQ<\/a> is an open-source distributed messaging and streaming data platform (yet another contribution from <a href=\"http:\/\/www.alibaba.com\">Alibaba<\/a>). It aims for extremely low latency, high availability and massive message capacity.<\/p>\n<h3><a name=\"nats\"><\/a>5.9. NATS<\/h3>\n<p><a href=\"https:\/\/nats.io\/\">NATS<\/a> is a simple, high performance open source messaging system for cloud-native applications, IoT messaging, and <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservice architectures<\/a>. It implements a highly scalable and elegant publish-subscribe message distribution model.<\/p>\n<h3><a name=\"nsq\"><\/a>5.10. NSQ<\/h3>\n<p><a href=\"http:\/\/nsq.io\/\">NSQ<\/a> is an open-source realtime distributed messaging platform, designed to operate at scale and handle billions of messages per day. It also follows a broker-less model and as such has no single point of failure, supports high-availability and horizontal scalability.<\/p>\n<h2><a name=\"all\"><\/a>6. Get It All<\/h2>\n<p>There is a certain class of libraries which have a sole intention to seamlessly bridge many different communication channels together. Collectively, they are known as integration frameworks and are heavily inspired by terrific <a href=\"https:\/\/www.enterpriseintegrationpatterns.com\/\">Enterprise Integration Patters<\/a> book.<\/p>\n<h3><a name=\"camel\"><\/a>6.1. Apache Camel<\/h3>\n<p><a href=\"http:\/\/camel.apache.org\/\">Apache Camel<\/a> is a powerful and mature open source integration framework. It is a surprisingly small library with a minimal set of dependencies and easily embeddable in any Java application. It abstracts away the kind of transports used behind a concise API layer which allows the interaction with <a href=\"https:\/\/github.com\/apache\/camel\/blob\/master\/components\/readme.adoc#components\">more than 300 components<\/a> provided out of the box.<\/p>\n<h3><a name=\"spring\"><\/a>6.2. Spring Integration<\/h3>\n<p><a href=\"https:\/\/spring.io\/projects\/spring-integration\">Spring Integration<\/a>, another great member of the <a href=\"https:\/\/spring.io\/\">Spring<\/a> projects portfolio, enables lightweight messaging and integration with external systems. It is primarily used within <a href=\"https:\/\/spring.io\/\">Spring<\/a>-based applications and services, providing outstanding interoperability with all other <a href=\"https:\/\/spring.io\/\">Spring<\/a> projects.<\/p>\n<blockquote>\n<p><a href=\"https:\/\/spring.io\/projects\/spring-integration\"><em>Spring Integration<\/em><\/a><em>\u2019s primary goal is to provide a simple model for building enterprise integration solutions while maintaining the separation of concerns that is essential for producing maintainable, testable code. &#8211; <\/em><a href=\"https:\/\/spring.io\/projects\/spring-integration\"><em>https:\/\/spring.io\/projects\/spring-integration<\/em><\/a><\/p>\n<\/blockquote>\n<p>If your <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservices<\/a> are built on top of <a href=\"https:\/\/spring.io\/\">Spring Framework<\/a>, the <a href=\"https:\/\/spring.io\/projects\/spring-integration\">Spring Integration<\/a> is a logical choice to make (in case its need is justified and it fits into the overall architecture).<\/p>\n<h2><a name=\"cloud\"><\/a>7. What about Cloud?<\/h2>\n<p>Along this part of the tutorial we have talked about open-source libraries and frameworks, which could be used either in on-premise deployments or in the cloud. They are generally agnostic to the vendor but many cloud providers have own biases towards one framework or another. More to that, besides offering own managed services, specifically in the messaging and data streaming space, the cloud vendors are heavily gravitating towards <a href=\"https:\/\/en.wikipedia.org\/wiki\/Serverless_computing\">serverless computing<\/a>, primarily in the shape of the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Function_as_a_service\">function as a service<\/a>.<\/p>\n<h2><a name=\"things\"><\/a>8. But There Are a Lot More \u2026<\/h2>\n<p>Fairly speaking, there are too many different libraries and frameworks to talk about. We have been discussing the most widely used ones but there are much, much more. Let us just mention some of them briefly.<\/p>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/OSGi\">OSGi<\/a> and its distributed counterpart, <a href=\"http:\/\/cxf.apache.org\/distributed-osgi.html\">DOSGi<\/a>, were known to be the only true way to build modular system and platforms in Java. Although it is not a simple one to deal with, it could be very well suited for implementing <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservices<\/a>.<\/p>\n<p><a href=\"https:\/\/github.com\/ReactiveX\/RxNetty\">RxNetty<\/a> is a pretty low-level reactive extension adaptor for <a href=\"https:\/\/netty.io\/\">Netty<\/a>, quite helpful if you need an engine with very low overhead.<\/p>\n<p><a href=\"https:\/\/github.com\/linkedin\/rest.li\">Rest.li<\/a> (from <a href=\"https:\/\/developer.linkedin.com\/\">Linkedin<\/a>) is a framework for building robust, scalable <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">RESTful web services<\/a> architectures using dynamic discovery and simple asynchronous APIs.<\/p>\n<p><a href=\"https:\/\/pulsar.incubator.apache.org\/\">Apache Pulsar<\/a> is a multi-tenant, high performance, very low latency solution for server-to-server messaging which was originally developed by <a href=\"http:\/\/yahoo.github.io\/\">Yahoo<\/a>.<\/p>\n<h2><a name=\"conclusions\"><\/a>9. Java \/ JVM Landscape &#8211; Conclusions<\/h2>\n<p>In this section of the tutorial we paged through tons of the different libraries and frameworks which are used today to build <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservices<\/a> in Java (and JVM in general). Every one of them has own niche but it does not make the decision process any easier. Importantly, the today\u2019s architecture may not reflect the tomorrow\u2019s reality: you have to pick the stack which could scale with your <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservices<\/a> for years to come.<\/p>\n<h2><a name=\"next\"><\/a>10. What\u2019s next<\/h2>\n<p>In the next section of the tutorial we are going to talk about monoglot versus polyglot <a href=\"https:\/\/en.wikipedia.org\/wiki\/Microservices\">microservices<\/a> and outline the reference application to serve as a playground for our future topics.<\/p>\n<p>The complete set of sample projects is <a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/09\/section-3.zip\">available for download<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. Introduction In the previous part of the tutorial we have covered a broad range of communication styles widely used while building microservices. It is time to put this knowledge into practical perspective by talking about most popular and battle-tested Java libraries and frameworks which may serve as the foundation of your microservice architecture implementation. &hellip;<\/p>\n","protected":false},"author":141,"featured_media":2386,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15],"tags":[960],"class_list":["post-81675","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software-development","tag-microservices"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Microservices for Java Developers: The Java \/ JVM Landscape - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Interested to learn more about Microservices? Then check out our detailed Tutorial on Java \/ JVM Landscape!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2018\/09\/microservices-java-developers-java-jvm-landscape.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Microservices for Java Developers: The Java \/ JVM Landscape - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Interested to learn more about Microservices? Then check out our detailed Tutorial on Java \/ JVM Landscape!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2018\/09\/microservices-java-developers-java-jvm-landscape.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2018-09-13T13:00:21+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-12-11T10:27:15+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Andrey Redko\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andrey Redko\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"18 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/microservices-java-developers-java-jvm-landscape.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/microservices-java-developers-java-jvm-landscape.html\"},\"author\":{\"name\":\"Andrey Redko\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/771a6504862edc45322776832cbce413\"},\"headline\":\"Microservices for Java Developers: The Java \\\/ JVM Landscape\",\"datePublished\":\"2018-09-13T13:00:21+00:00\",\"dateModified\":\"2023-12-11T10:27:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/microservices-java-developers-java-jvm-landscape.html\"},\"wordCount\":4147,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/microservices-java-developers-java-jvm-landscape.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/software-development-2-logo.jpg\",\"keywords\":[\"Microservices\"],\"articleSection\":[\"Software Development\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/microservices-java-developers-java-jvm-landscape.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/microservices-java-developers-java-jvm-landscape.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/microservices-java-developers-java-jvm-landscape.html\",\"name\":\"Microservices for Java Developers: The Java \\\/ JVM Landscape - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/microservices-java-developers-java-jvm-landscape.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/microservices-java-developers-java-jvm-landscape.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/software-development-2-logo.jpg\",\"datePublished\":\"2018-09-13T13:00:21+00:00\",\"dateModified\":\"2023-12-11T10:27:15+00:00\",\"description\":\"Interested to learn more about Microservices? Then check out our detailed Tutorial on Java \\\/ JVM Landscape!\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/microservices-java-developers-java-jvm-landscape.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/microservices-java-developers-java-jvm-landscape.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/microservices-java-developers-java-jvm-landscape.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/software-development-2-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/software-development-2-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/09\\\/microservices-java-developers-java-jvm-landscape.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Software Development\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/software-development\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Microservices for Java Developers: The Java \\\/ JVM Landscape\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/771a6504862edc45322776832cbce413\",\"name\":\"Andrey Redko\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g\",\"caption\":\"Andrey Redko\"},\"description\":\"Andriy is a well-grounded software developer with more then 12 years of practical experience using Java\\\/EE, C#\\\/.NET, C++, Groovy, Ruby, functional programming (Scala), databases (MySQL, PostgreSQL, Oracle) and NoSQL solutions (MongoDB, Redis).\",\"sameAs\":[\"http:\\\/\\\/aredko.blogspot.com\\\/\",\"http:\\\/\\\/ca.linkedin.com\\\/in\\\/aredko\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/andrey-redko\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Microservices for Java Developers: The Java \/ JVM Landscape - Java Code Geeks","description":"Interested to learn more about Microservices? Then check out our detailed Tutorial on Java \/ JVM Landscape!","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2018\/09\/microservices-java-developers-java-jvm-landscape.html","og_locale":"en_US","og_type":"article","og_title":"Microservices for Java Developers: The Java \/ JVM Landscape - Java Code Geeks","og_description":"Interested to learn more about Microservices? Then check out our detailed Tutorial on Java \/ JVM Landscape!","og_url":"https:\/\/www.javacodegeeks.com\/2018\/09\/microservices-java-developers-java-jvm-landscape.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2018-09-13T13:00:21+00:00","article_modified_time":"2023-12-11T10:27:15+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg","type":"image\/jpeg"}],"author":"Andrey Redko","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Andrey Redko","Est. reading time":"18 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2018\/09\/microservices-java-developers-java-jvm-landscape.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/09\/microservices-java-developers-java-jvm-landscape.html"},"author":{"name":"Andrey Redko","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/771a6504862edc45322776832cbce413"},"headline":"Microservices for Java Developers: The Java \/ JVM Landscape","datePublished":"2018-09-13T13:00:21+00:00","dateModified":"2023-12-11T10:27:15+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/09\/microservices-java-developers-java-jvm-landscape.html"},"wordCount":4147,"commentCount":1,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/09\/microservices-java-developers-java-jvm-landscape.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg","keywords":["Microservices"],"articleSection":["Software Development"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2018\/09\/microservices-java-developers-java-jvm-landscape.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2018\/09\/microservices-java-developers-java-jvm-landscape.html","url":"https:\/\/www.javacodegeeks.com\/2018\/09\/microservices-java-developers-java-jvm-landscape.html","name":"Microservices for Java Developers: The Java \/ JVM Landscape - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/09\/microservices-java-developers-java-jvm-landscape.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/09\/microservices-java-developers-java-jvm-landscape.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg","datePublished":"2018-09-13T13:00:21+00:00","dateModified":"2023-12-11T10:27:15+00:00","description":"Interested to learn more about Microservices? Then check out our detailed Tutorial on Java \/ JVM Landscape!","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/09\/microservices-java-developers-java-jvm-landscape.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2018\/09\/microservices-java-developers-java-jvm-landscape.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2018\/09\/microservices-java-developers-java-jvm-landscape.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2018\/09\/microservices-java-developers-java-jvm-landscape.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Software Development","item":"https:\/\/www.javacodegeeks.com\/category\/software-development"},{"@type":"ListItem","position":3,"name":"Microservices for Java Developers: The Java \/ JVM Landscape"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/771a6504862edc45322776832cbce413","name":"Andrey Redko","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g","caption":"Andrey Redko"},"description":"Andriy is a well-grounded software developer with more then 12 years of practical experience using Java\/EE, C#\/.NET, C++, Groovy, Ruby, functional programming (Scala), databases (MySQL, PostgreSQL, Oracle) and NoSQL solutions (MongoDB, Redis).","sameAs":["http:\/\/aredko.blogspot.com\/","http:\/\/ca.linkedin.com\/in\/aredko"],"url":"https:\/\/www.javacodegeeks.com\/author\/andrey-redko"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/81675","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/141"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=81675"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/81675\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/2386"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=81675"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=81675"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=81675"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}