Skip to content
This repository was archived by the owner on Aug 13, 2020. It is now read-only.

Messaging between Service Components

matt-rich edited this page Dec 19, 2016 · 9 revisions

Introduction

The framework has been designed with microservices in mind, separating the individual Service Components (Command API, Query View etc.) into encapsulated cohesive microservices that communicate over via Http or JMS.

Each service defines its API through its RAML definition(s) and the framework is capable of harnessing these RAML definitions to generate clients capable of communicating with each other. As documented in the <RAML documentation section - TODO> each service can generate a jar file containing its RAML definitions, which can then be used as a maven dependency to allow client services to communicate with it.

Generating Clients

The framework can generate clients to communicate with a service, based on its RAML definitions. This avoids the need for manually creating REST or JMS clients for allowing cross service communications.

The generated clients are written to the target/generated-sources directory and should not be altered manually as any changes will be overwritten. These clients are available as CDI beans within the application context ready to be injected and used as required within your service.

To use one of the generated clients you need to use the @Inject annotation over either a Requester or Sender interface, depending on whether synchronous or asynchronous communications are required.

@ServiceComponent(QUERY_API)
public class RecipesQueryApi {

    @Inject
    Requester requester;

    @Handles("example.get-recipe")
    public JsonEnvelope getRecipe(final JsonEnvelope query) {
        return requester.request(query);
    }
}

Binding Annotations

The framework will bind and inject the appropriate client to the implementing class through the use of framework annotations coupled with the POM configuration (Details below). Either the @ServiceComponent or @FrameworkComponent annotation should be present on the class or directly on the injected Requester/Sender member variable. Where the client injection is occurring within one of the core ServiceComponent services (e.g. in a handler class) then the @ServiceComponent annotation should be used, whereas the @FrameworkComponent is used for injecting in all other classes.

@Remote
@FrameworkComponent("QUERY_API")
public final class RemoteCakeshopQueryController {
  private static final String BASE_URI = "http://localhost:8080/example-query-controller/query/controller/rest/cakeshop";

  @Inject
  RestClientProcessor restClientProcessor;

  @Inject
  RestClientHelper restClientHelper;

  @Inject
  Enveloper enveloper;

  @Handles("example.get-recipe")
  public JsonEnvelope getExampleRecipe(final JsonEnvelope envelope) {
    LoggerUtils.trace(LOGGER, () -> String.format("Handling remote request: %s", envelope));
    final String path = "/recipes/{recipeId}";
    final Set<String> pathParams = restClientHelper.extractPathParametersFromPath(path);
    final Set<QueryParam> queryParams = new HashSet<QueryParam>();
    final EndpointDefinition def = new EndpointDefinition(BASE_URI, path, pathParams, queryParams, "example.recipe");
    return restClientProcessor.get(def, envelope);
  }
}

POM configuration

Depend on RAML @ServiceCOmponent, property etc.

Usage

Clone this wiki locally