{"id":79987,"date":"2020-05-02T01:42:42","date_gmt":"2020-05-01T23:42:42","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/kak-quarkus-obedinyaet-microprofile-i-spring"},"modified":"2020-05-02T01:42:42","modified_gmt":"2020-05-01T23:42:42","slug":"kak-quarkus-obedinyaet-microprofile-i-spring","status":"publish","type":"post","link":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/kak-quarkus-obedinyaet-microprofile-i-spring","title":{"rendered":"How Quarkus Combines MicroProfile and Spring","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Hello everyone, and welcome to the third post in our series about Quarkus!<\/p>\n<p><img decoding=\"async\" alt=\"How Quarkus Combines MicroProfile and Spring\" src=\"\/wp-content\/uploads\/2020\/05\/d98ff470b49f8de1fa488a6818160969.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWhen developing Java microservices, it is often considered that <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2019\/02\/28\/jumpstart-microservices-microprofile-starter-beta\/\">Eclipse MicroProfile<\/a><\/noindex> and <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/topics\/spring-boot\/\">Spring Boot<\/a><\/noindex> are separate and independent APIs from each other. Typically, programmers tend to use the APIs they are already familiar with, as learning new frameworks and runtime components takes time. Today we will try to simplify the learning of some popular <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2018\/11\/21\/eclipse-microprofile-for-spring-boot-developers\/\">MicroProfile APIs for Spring developers<\/a><\/noindex> and show how to simultaneously leverage Spring APIs and new useful features. <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/\">Quarkus<\/a><\/noindex>.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nTo elaborate, we will first look at the use cases and details of how Quarkus supports Spring APIs to demonstrate to Spring developers how MicroProfile APIs can be applied in their daily work. Then we will discuss the MicroProfile APIs that will be useful for Spring developers when creating microservices.<\/p>\n<p>Why Quarkus? Firstly, it supports live coding, meaning any changes made to the MicroProfile APIs, Spring APIs, and other Java APIs are automatically reloaded with just one command: mvn quarkus:dev. Secondly, the service described in <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jclingan\/quarkus-spring-microprofile\">our example<\/a><\/noindex> the Person service (which compiles from Spring, MicroProfile, and JPA APIs into a binary file using the GraalVM native image) starts in just 0.055 seconds and consumes about 90 MB of RAM (RSS) at the RESTful application's endpoint. The compilation itself is completed with a single command: mvn package -Pnative.<\/p>\n<p>We will not delve into the details of MicroProfile but will strive to help Spring developers understand how Spring APIs can be used along with MicroProfile APIs in Quarkus.<\/p>\n<h3>Containers and Kubernetes<\/h3>\n<p>\nTo avoid overwhelming this article, we will only consider high-level aspects of support <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/developer-tools\/kubernetes\">Kubernetes<\/a><\/noindex>, as it's important to understand. Quarkus is positioned as a Java stack for Kubernetes, designed to minimize memory usage and startup time for Java applications and services, thereby increasing their density on the host and reducing overall costs.<\/p>\n<p>Quarkus also <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/kubernetes-resources\">supports auto-generation<\/a><\/noindex> of Kubernetes resources and offers <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/\">guides<\/a><\/noindex> for deployment on Kubernetes and Red Hat OpenShift platforms. Additionally, Quarkus automatically generates Dockerfile.jvm (JVM packaging) and Dockerfile.native (native binary packaging) files necessary for container creation.<\/p>\n<p>Finally, focusing on Kubernetes as the target deployment environment, Quarkus does not use Java frameworks where equivalent functionality is realized at the Kubernetes platform level. Table 1 presents a mapping of functional equivalence between Kubernetes and typical Java frameworks used by Spring developers.<\/p>\n<p><i>Table 1. Mapping of functional equivalence between Java frameworks and Kubernetes.<\/i><\/p>\n<p>Functionality<br \/>\nTraditional Spring Boot<br \/>\nKubernetes<\/p>\n<p>Service discovery<br \/>\nEureka<br \/>\nDNS<\/p>\n<p>Configuration<br \/>\nSpring Cloud Config<br \/>\nConfig Maps \/ Secrets<\/p>\n<p>Load Balancing<br \/>\nRibbon (client-side)<br \/>\nService, Replication Controller (server-side)<\/p>\n<p><\/p>\n<h3>Compiling and running the example code<\/h3>\n<p>\nIn this article, we refer to <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jclingan\/quarkus-spring-microprofile\">the project example<\/a><\/noindex>, where the Spring and MicroProfile APIs are used together, along with the very same Java class. The code from this example can be compiled and run from the command line; for more details, see the README.md file.<\/p>\n<h3>Spring Framework APIs<\/h3>\n<p><\/p>\n<h4>Dependency Injection<\/h4>\n<p>\nQuarkus supports a wide range of <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/cdi-reference\">Contexts and Dependency Injection (CDI) APIs<\/a><\/noindex> and Spring Dependency Injection (Spring DI) APIs. If you are working with MicroProfile, <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2019\/09\/12\/jakarta-ee-8-the-new-era-of-java-ee-explained\/\">Java EE and Jakarta EE<\/a><\/noindex>, you are likely familiar with CDI. On the other hand, Spring developers can use the Quarkus Extension for Spring DI API for compatibility with Spring DI. Examples of using supported Spring DI APIs are provided in Table 2.<\/p>\n<p>In <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jclingan\/quarkus-spring-microprofile\">the project from our example<\/a><\/noindex> utilizes both CDI and Spring Dependency Injection. More information and examples on this topic can be found in the Quarkus guide titled <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/spring-di\">Spring DI Guide<\/a><\/noindex>.<\/p>\n<p><i>Table 2. Examples of using supported Spring DI APIs.<\/i><\/p>\n<p>Supported Spring DI features<br \/>\nExamples<\/p>\n<p>Constructor Injection<\/p>\n<pre><code class=\"plaintext\">public PersonSpringController(\n   PersonSpringRepository personRepository,  \/\/ injected      \n   PersonSpringMPService personService) {    \/\/ injected\n      this.personRepository = personRepository;\n      this.personService = personService;\n}\n<\/code><\/pre>\n<p>Field Injection<br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/autowired\/\" class=\"user_link\">Autowired<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/value\/\" class=\"user_link\">Value<\/a><\/noindex><\/p>\n<pre><code class=\"plaintext\">@Autowired\n@RestClient\nSalutationRestClient salutationRestClient;\n\n@Value(\"${fallbackSalutation}\")\nString fallbackSalutation;\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/bean\/\" class=\"user_link\">Bean<\/a><\/noindex><br \/>\n@Configuration<\/p>\n<pre><code class=\"plaintext\">@Configuration\npublic class AppConfiguration {\n   @Bean(name = \"capitalizeFunction\")\n   public StringFunction capitalizer() {\n      return String::toUpperCase;\n   }\n}\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/component\/\" class=\"user_link\">Component<\/a><\/noindex><\/p>\n<pre><code class=\"plaintext\">@Component(\"noopFunction\")\npublic class NoOpSingleStringFunction implements StringFunction {\n   @Override\n   public String apply(String s) {\n      return s;\n   }\n}\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/service\/\" class=\"user_link\">Service<\/a><\/noindex><\/p>\n<pre><code class=\"plaintext\">@Service\npublic class MessageProducer {\n   @Value(\"${greeting.message}\")\n   String message;\n\n   public String getPrefix() {\n      return message;\n   }\n}\n<\/code><\/pre>\n<p><\/p>\n<h4>Web framework<\/h4>\n<p>\nMicroProfile users will appreciate that Quarkus supports JAX-RS, MicroProfile Rest Client, JSON-P, and JSON-B as the primary web programming model. Spring developers will be pleased with the recently added support for Spring Web API in Quarkus, particularly interfaces responsible for REST. Similar to Spring DI, the main goal of supporting Spring Web API is to allow Spring developers to use Spring Web interfaces alongside MicroProfile interfaces. Examples of using supported Spring Web APIs are provided in Table 3, and additional information and examples on this topic can be found in the Quarkus guide titled <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/spring-web\">Spring Web Guide<\/a><\/noindex>.<\/p>\n<p><i>Table 3. Examples of using supported Spring Web API interfaces.<\/i><\/p>\n<p>Supported Spring Web Features<br \/>\nExamples<\/p>\n<p>@RestController<br \/>\n@RequestMapping<\/p>\n<pre><code class=\"plaintext\">@RestController\n@RequestMapping(\"\/person\")\npublic class PersonSpringController {\n   ...\n   ...\n   ...\n}\n<\/code><\/pre>\n<p>@GetMapping<br \/>\n@PostMapping<br \/>\n@PutMapping<br \/>\n@DeleteMapping<br \/>\n@PatchMapping<br \/>\n@RequestParam<br \/>\n@RequestHeader<br \/>\n@MatrixVariable<br \/>\n@PathVariable<br \/>\n@CookieValue<br \/>\n@RequestBody<br \/>\n@ResponseStatus<br \/>\n@ExceptionHandler<br \/>\n@RestControllerAdvice (partial)<\/p>\n<pre><code class=\"plaintext\">@GetMapping(path = \"\/greet\/{id}\",\n   produces = \"text\/plain\")\n   public String greetPerson(\n   @PathVariable(name = \"id\") long id) {\n   ...\n   ...\n   ...\n}\n<\/code><\/pre>\n<p><\/p>\n<h4>Spring Data JPA<\/h4>\n<p>\nMicroProfile users will also be pleased that Quarkus supports JPA using Hibernate ORM. Spring developers have good news as well: Quarkus supports standard annotations and types from Spring Data JPA. Examples of using supported Spring Data JPA APIs are provided in Table 4.<br \/>\nIn <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jclingan\/quarkus-spring-microprofile\">the project from our example<\/a><\/noindex> Spring Data JPA APIs are used, and additional information is available in the Quarkus guide titled <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/spring-data-jpa-guide\">Spring Data JPA Guide<\/a><\/noindex>.<\/p>\n<p><i>Table 4. Examples of using supported Spring Data JPA API interfaces.<\/i><\/p>\n<p>Supported Spring Data JPA Features<br \/>\nExamples<\/p>\n<p>CrudRepository<\/p>\n<pre><code class=\"plaintext\">public interface PersonRepository\n         extends JpaRepository,\n                 PersonFragment {\n   ...\n}\n<\/code><\/pre>\n<p>Repository<br \/>\nJpaRepository<br \/>\nPagingAndSortingRepository<\/p>\n<pre><code class=\"plaintext\">public class PersonRepository extends \n\n    Repository {\n\n    Person save(Person entity);\n\n    Optional findById(Person entity);\n}\n<\/code><\/pre>\n<p>Repository Fragments<\/p>\n<pre><code class=\"plaintext\">public interface PersonRepository\n         extends JpaRepository,\n                 PersonFragment {\n   ...\n}\n<\/code><\/pre>\n<p>Derived query methods<\/p>\n<pre><code class=\"plaintext\">public interface PersonRepository extends CrudRepository {\n\n    List findByName(String name);\n    \n    Person findByNameBySsn(String ssn);\n    \n    Optional \n       findByNameBySsnIgnoreCase(String ssn);\n\n    Boolean existsBookByYearOfBirthBetween(\n            Integer start, Integer end);\n}\n<\/code><\/pre>\n<p>User-defined queries<\/p>\n<pre><code class=\"plaintext\">public interface MovieRepository\n         extends CrudRepository {\n\n    Movie findFirstByOrderByDurationDesc();\n\n    @Query(\"select m from Movie m where m.rating = ?1\")\n    Iterator findByRating(String rating);\n\n    @Query(\"from Movie where title = ?1\")\n    Movie findByTitle(String title);\n}\n<\/code><\/pre>\n<p><\/p>\n<h3>MicroProfile APIs<\/h3>\n<p><\/p>\n<h4>Fault tolerance<\/h4>\n<p>\nFault tolerance constructs are crucial for preventing cascading failures and creating reliable microservices architectures. Spring developers have been using circuit breakers for fault tolerance for many years. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/Netflix\/Hystrix\">Hystrix<\/a><\/noindex>. However, Hystrix has not been updated for a long time, while the MicroProfile Fault Tolerance is actively being developed and has several years of production use behind it. Therefore, to enhance service reliability in Quarkus, it is recommended to use the MicroProfile Fault Tolerance APIs, with usage examples provided in Table 5. Additional information can be found in the Quarkus guide. <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/microprofile-fault-tolerance\">Fault Tolerance Guide<\/a><\/noindex>.<\/p>\n<p><i>Table 5. Examples of using supported MicroProfile Fault Tolerance APIs.<\/i><\/p>\n<p>MicroProfile Fault Tolerance Features<br \/>\nDescription<br \/>\nExamples<\/p>\n<p>@Asynchronous<\/p>\n<p>Execution of logic in a separate thread<\/p>\n<pre><code class=\"plaintext\">@Asynchronous\n@Retry\npublic Future getSalutation() {\n   ...\n   return future;\n}\n<\/code><\/pre>\n<p>@Bulkhead<\/p>\n<p>Limiting the number of concurrent requests<\/p>\n<pre><code class=\"plaintext\">@Bulkhead(5)\npublic void fiveConcurrent() {\n   makeRemoteCall(); \/\/...\n}\n<\/code><\/pre>\n<p>@CircuitBreaker<\/p>\n<p>Intelligent failure handling and recovery from failures<\/p>\n<pre><code class=\"plaintext\">@CircuitBreaker(delay=500   \/\/ milliseconds\n   failureRatio = .75,\n   requestVolumeThreshold = 20,\n   successThreshold = 5)\n@Fallback(fallbackMethod = \"fallback\")\npublic String getSalutation() {\n   makeRemoteCall(); \/\/...\n}\n<\/code><\/pre>\n<p>@Fallback<\/p>\n<p>Invoking alternative logic in case of failure<\/p>\n<pre><code class=\"plaintext\">@Timeout(500) \/\/ milliseconds\n@Fallback(fallbackMethod = \"fallback\")\npublic String getSalutation() {\n   makeRemoteCall(); \/\/...\n}\n\npublic String fallback() {\n   return \"hello\";\n}\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/retry\/\" class=\"user_link\">Retry<\/a><\/noindex><\/p>\n<p>Retry on request failure<\/p>\n<pre><code class=\"plaintext\">@Retry(maxRetries=3)\npublic String getSalutation() {\n   makeRemoteCall(); \/\/...\n}\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/timeout\/\" class=\"user_link\">Timeout<\/a><\/noindex><\/p>\n<p>Control time limit on failure<\/p>\n<pre><code class=\"plaintext\">@Timeout(value = 500)   \/\/ milliseconds\n@Fallback(fallbackMethod = \"fallback\")\npublic String getSalutation() {\n   makeRemoteCall(); \/\/...\n}\n<\/code><\/pre>\n<p><\/p>\n<h4>Service Health Check<\/h4>\n<p>\nKubernetes platforms monitor the health of containers using special services. For the underlying platform to monitor services, Spring developers typically use customizable HealthIndicator and Spring Boot Actuator. In Quarkus, this can be done with MicroProfile Health, which by default performs liveness checks but can also be configured to check both liveness and readiness simultaneously. Examples of using supported MicroProfile Health APIs are provided in Table 6, and additional information is presented in the Quarkus guide. <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/microprofile-health\">Health Guide<\/a><\/noindex>.<\/p>\n<p><i>Table 6. Examples of using supported MicroProfile Health APIs.<\/i><\/p>\n<p>MicroProfile Health Features<br \/>\nDescription<br \/>\nExamples<\/p>\n<p>@Liveness<\/p>\n<p>The platform performs a restart of faulty containerized applications<br \/>\nEndpoint:<br \/>\nhost:8080\/health\/live<\/p>\n<pre><code class=\"plaintext\">@Liveness\npublic class MyHC implements HealthCheck {\n  public HealthCheckResponse call() {\n\n   ...\n   return HealthCheckResponse\n     .named(\"myHCProbe\")\n     .status(ready ? true:false)\n     .withData(\"mydata\", data)\n     .build();  \n}\n<\/code><\/pre>\n<p>@Readiness<\/p>\n<p>The platform will not route traffic to containerized applications if they are not ready.<br \/>\nEndpoint:<br \/>\nhost:8080\/health\/ready<\/p>\n<pre><code class=\"plaintext\">@Readiness\npublic class MyHC implements HealthCheck {\n  public HealthCheckResponse call() {\n\n   ...\n   return HealthCheckResponse\n     .named(\"myHCProbe\")\n     .status(live ? true:false)\n     .withData(\"mydata\", data)\n     .build();  \n}\n<\/code><\/pre>\n<p><\/p>\n<h4>Metrics<\/h4>\n<p>\nApplications provide metrics either for operational purposes (to monitor SLA performance indicators) or for non-operational ones (business SLA metrics). Spring developers provide metrics using Spring Boot Actuator and Micrometer. Quarkus, on the other hand, uses MicroProfile Metrics to provide basic metrics (JVM and operating system), vendor metrics (Quarkus), and application metrics. MicroProfile Metrics requires implementations to support output formats in JSON and OpenMetrics (Prometheus). Examples of using the MicroProfile Metrics API are provided in Table 7.<\/p>\n<p>In <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jclingan\/quarkus-spring-microprofile\">the project from our example<\/a><\/noindex> MicroProfile Metrics are used to provide application metrics. For more information, refer to the Quarkus guide. <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/microprofile-metrics\">Metrics Guide<\/a><\/noindex>.<\/p>\n<p><i>Table 7. Examples of using the MicroProfile Metrics APIs.<\/i><\/p>\n<p>MicroProfile Metrics Features<br \/>\nDescription<br \/>\nExamples<\/p>\n<p>@Counted<\/p>\n<p>Indicates a counter that counts the number of invocations of the annotated object.<\/p>\n<pre><code class=\"plaintext\">@Counted(name = \"fallbackCounter\", \n  displayName = \"Fallback Counter\", \n  description = \"Fallback Counter\")\npublic String salutationFallback() {\n   return fallbackSalutation;\n}\n<\/code><\/pre>\n<p>@ConcurrentGauge<\/p>\n<p>Indicates a gauge that counts the number of concurrent invocations of the annotated object.<\/p>\n<pre><code class=\"plaintext\">@ConcurrentGuage(\n  name = \"fallbackConcurrentGauge\", \n  displayName=\"Fallback Concurrent\", \n  description=\"Fallback Concurrent\")\npublic String salutationFallback() {\n   return fallbackSalutation;\n}\n<\/code><\/pre>\n<p>@Gauge<\/p>\n<p>Indicates a gauge that measures the value of the annotated object.<\/p>\n<pre><code class=\"plaintext\">@Metered(name = \"FallbackGauge\",\n   displayName=\"Fallback Gauge\",\n   description=\"Fallback frequency\")\npublic String salutationFallback() {\n   return fallbackSalutation;\n}\n<\/code><\/pre>\n<p>@Metered<\/p>\n<p>Indicates a meter that tracks the frequency of invocations of the annotated object.<\/p>\n<pre><code class=\"plaintext\">@Metered(name = \"MeteredFallback\",\n   displayName=\"Metered Fallback\",\n   description=\"Fallback frequency\")\npublic String salutationFallback() {\n   return fallbackSalutation;\n}\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/metric\/\" class=\"user_link\">Metric<\/a><\/noindex><\/p>\n<p>Annotation that contains metadata information upon receiving a request to create or produce a metric.<\/p>\n<pre><code class=\"plaintext\">@Metric\n@Metered(name = \"MeteredFallback\",\n   displayName=\"Metered Fallback\",\n   description=\"Fallback frequency\")\npublic String salutationFallback() {\n   return fallbackSalutation;\n}\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/timed\/\" class=\"user_link\">Timed<\/a><\/noindex><\/p>\n<p>Indicates a timer that tracks the duration of the annotated object.<\/p>\n<pre><code class=\"plaintext\">@Timed(name = \"TimedFallback\",\n   displayName=\"Timed Fallback\",\n   description=\"Fallback delay\")\npublic String salutationFallback() {\n   return fallbackSalutation;\n}\n<\/code><\/pre>\n<p>\n<b>Metrics Endpoints<\/b><\/p>\n<p>Application Metrics <noindex><a rel=\"nofollow\" href=\"http:\/\/localhost\">localhost<\/a><\/noindex>:8080\/metrics\/application<br \/>\nBasic Metrics <noindex><a rel=\"nofollow\" href=\"http:\/\/localhost\">localhost<\/a><\/noindex>:8080\/metrics\/base<br \/>\nVendor Metrics <noindex><a rel=\"nofollow\" href=\"http:\/\/localhost\">localhost<\/a><\/noindex>:8080\/metrics\/vendor<br \/>\nAll Metrics <noindex><a rel=\"nofollow\" href=\"http:\/\/localhost\">localhost<\/a><\/noindex>:8080\/metrics<\/p>\n<h4>MicroProfile REST Client<\/h4>\n<p>\nMicroservices often provide RESTful endpoints, which require corresponding client APIs to interact with. Spring developers typically use RestTemplate for this purpose. In contrast, Quarkus offers MicroProfile REST Client APIs to address this need, with usage examples provided in Table 8.<\/p>\n<p>In <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jclingan\/quarkus-spring-microprofile\">the project from our example<\/a><\/noindex> Using RESTful endpoints is done via the MicroProfile REST Client. For more information and examples, please refer to the Quarkus guide. <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/rest-client\">Rest Client Guide<\/a><\/noindex>.<\/p>\n<p><i>Table 8. Examples of using MicroProfile REST Client APIs.<\/i><\/p>\n<p>Features of MicroProfile REST Client<br \/>\nDescription<br \/>\nExamples<\/p>\n<p>@RegisterRestClient<\/p>\n<p>Registers a typed Java interface as a REST client<\/p>\n<pre><code class=\"plaintext\">@RegisterRestClient\n@Path(\"\/\")\npublic interface MyRestClient {\n    @GET\n    @Produces(MediaType.TEXT_PLAIN)\n    public String getSalutation();\n}\n<\/code><\/pre>\n<p>@RestClient<\/p>\n<p>Marks an instance of a typed REST client interface for dependency injection<\/p>\n<pre><code class=\"plaintext\">@Autowired \/\/ or @Inject\n@RestClient\nMyRestClient restClient;\n<\/code><\/pre>\n<p>Invocation<\/p>\n<p>Invokes the REST endpoint<\/p>\n<pre><code class=\"plaintext\">System.out.println(\n   restClient.getSalutation());\n<\/code><\/pre>\n<p>mp-rest\/url<\/p>\n<p>Sets the REST endpoint<\/p>\n<pre><code class=\"plaintext\">application.properties:\norg.example.MyRestClient\/mp-rest\/url=\n   http:\/\/localhost:8081\/myendpoint\n<\/code><\/pre>\n<p><\/p>\n<h3>Summary<\/h3>\n<p>\nIn this blog, primarily useful for Spring developers, we briefly examined how to use Spring APIs alongside MicroProfile APIs in Quarkus to develop Java microservices and then compile them into native binary code that saves hundreds of megabytes of memory and starts in mere milliseconds.<\/p>\n<p>As you may have understood, more information on the support for Spring and MicroProfile APIs, as well as a wealth of other useful information, can be found in <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/\">Quarkus Guides<\/a><\/noindex>.<br \/>\n<br \/>Source: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/redhatrussia\/blog\/497504\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u0438 \u0441 \u0432\u0430\u043c\u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u0441\u0435\u0440\u0438\u0438 \u043f\u0440\u043e Quarkus! \u041f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 Java-\u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0447\u0430\u0441\u0442\u043e \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e Eclipse MicroProfile \u0438 Spring Boot \u2013 \u044d\u0442\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0438 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u0434\u0440\u0443\u0433 \u043e\u0442 \u0434\u0440\u0443\u0433\u0430 API. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u044b, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0442\u0435 API, \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043e\u043d\u0438 \u0443\u0436\u0435 \u043f\u0440\u0438\u0432\u044b\u043a\u043b\u0438, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 \u0438 runtime-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":79988,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-79987","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u0438 \u0441 \u0432\u0430\u043c\u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u0441\u0435\u0440\u0438\u0438 \u043f\u0440\u043e Quarkus!\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/kak-quarkus-obedinyaet-microprofile-i-spring\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041a\u0430\u043a Quarkus \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 MicroProfile \u0438 Spring | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u0438 \u0441 \u0432\u0430\u043c\u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u0441\u0435\u0440\u0438\u0438 \u043f\u0440\u043e Quarkus!\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/kak-quarkus-obedinyaet-microprofile-i-spring\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-05-01T23:42:42+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-05-01T23:42:42+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47 How Quarkus Combines MicroProfile and Spring | ProHoster","description":"Hello everyone, and welcome to the third post in our series about Quarkus!","canonical_url":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/kak-quarkus-obedinyaet-microprofile-i-spring","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"en_US","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041a\u0430\u043a Quarkus \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 MicroProfile \u0438 Spring | ProHoster","og:description":"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u0438 \u0441 \u0432\u0430\u043c\u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u0441\u0435\u0440\u0438\u0438 \u043f\u0440\u043e Quarkus!","og:url":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/kak-quarkus-obedinyaet-microprofile-i-spring","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-05-01T23:42:42+00:00","article:modified_time":"2020-05-01T23:42:42+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"79987","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 16:27:13","updated":"2022-09-30 14:08:43","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts\/79987","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/comments?post=79987"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts\/79987\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/media\/79988"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/media?parent=79987"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/categories?post=79987"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/tags?post=79987"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}