How to design a service layer in Java using CRF
Tags: java, architecture, layering, crf
Published: 2017-07-05 13:21:22

---
published: true
title: How to design a service layer in Java using CRF
description: How to design a service / application layer in Java using CRF – Commands, Reactions and Funnels.
tags: 
- java
- architecture
- layering
- crf
---

## Intro

As part of my [Effective Java](http://devchampions.com/training/java/) course, I've been showing how to design a simple, but flexible service layer for Java applications with the approch I call **CRF**. Most attendees find the idea fresh and exciting, so I have decided to share it with the wider audience.

## Service layer?!

Let's briefly discuss what service layer is supposed to do. The purpose of the service layer is to:

1) Define a **use case**. In other words, when you look at the service layer, it should answer the question – what the system **is capable of doing**.

2) Define a **contract**. In other words, when you look at the particular use case / service, it should be clear what data inputs are required, what are the possible outputs, and what exceptions are thrown.

3) Define a **transaction boundary**. A use case either succeeds or fails. If it succeeds, the associated data is persisted. If it fails – the changes are rolled back. This is important, because different users can run many use cases in parallel. Say, if me (Eduards) and you (the reader) are trying to secure the same airplane seat, there are 2 instances of a use case (SecureASeat) running in parallel. In order to avoid double booking ([hello United Airlines](http://www.express.co.uk/travel/articles/790214/United-Airlines-passenger-dragged-overbooked-flight)), if you secure the seat first, my booking attempt must fail and all changes associated with my booking attempt (if any) must be rolled back.

There is much more to know about the service layer, but it's enough to set the common ground. 

Now, let's look at the most common way of building a service layer.

## Procedural service layer (Babushka style)

The most common style of a service layer is to use procedures.

Here is a service that allows messing with member permissions:

```java
interface MemberPermissionService {
  void grantPermission(String memberId, String permissionId);
  void revokePermission(String memberId, String permissionId);
  PermissionsDto listPermissions(String memberId);
  ...
}
```

Because we [program to an interface](https://en.wikipedia.org/wiki/Interface-based_programming), there is also the implementation:

```java
@Service
class MemberPermissionServiceImpl implements MemberPermissionService {
  @Override
  public void grantPermission(String memberId, String permissionId) { ... }
  
  @Override
  void revokePermission(String memberId, String permissionId) { ... }
  
  @Override
  public PermissionsDto listPermissions(String memberId) { ... }
}
```

Sometimes the interface is not used at all. Whether or no, it doesn't change the idea.

The aforementioned style is valid, but, as every design decision, it also has a set of drawbacks.


### Opaqueness

Imagine we are looking at the package where services are located:

```
net.blog.sizovs.services.MemberPermissionService
net.blog.sizovs.services.ModerationService
net.blog.sizovs.services.MemberService
```

Looking into the package, we can't get a solid understanding what the system is doing. We see that the system can do *something* with member permissions, *something* with moderation and *something* with members.

In order to understand what exactly the system can do, we have to open the services and see what procedures they contain. In other words, the service layer [does not scream](https://8thlight.com/blog/uncle-bob/2011/09/30/Screaming-Architecture.html) about what the system is capable of doing.


### Obesity
All use cases related to Member Permissions become methods of `MemberPermissionService` interface. The more uses cases – the more methods. 

The more methods an interface publishes, the higher is afferent coupling. 

The more an interface promises to do, the fatter will be the implementation (`MemberPermissionServiceImpl`).

Very likely, `MemberPermissionServiceImpl` will also suffer from high efferent coupling –  it will have many *outgoing* dependencies.

Large number of dependencies reduces testability.

It's like a snowball rolling down the hill. People just keep adding use cases to the same interface, because the interface has become a container for suitable uses cases. Sounds familiar?

### Always blocking

In our example, the service calls are blocking. Technically, we can make some services return `CompletableFuture` or `Observable`.

Likely, we'll end up with a separate method per execution model. Like this:

```java
interface MemberPermissionService {
  PermissionsDto listPermissions(String memberId);
  CompletableFuture<PermissionsDto> listPermissionAsync(String memberId);
  ...
}
```

Some teams prefer creating a separate interface:

```java
interface MemberPermissionServiceAsync {
  CompletableFuture<PermissionsDto> listPermissionAsync(String memberId);
  ...
}
```

It's more a matter of taste, rather than a conceptual difference.

Remember the rule – **encapsulate what varies**? The service is essentially the same, but the execution model varies. Can we do a better job? Surely we can. Read on.

> **Side-note**: what if we make all services return `CompletableFuture` from day 1 to support both blocking and non-blocking execution? Yes, we can! Nevertheless, there are other execution models such as "fire-and-forget", when you push the work into a message queue and the work is being run in the background. `CompletableFuture` won't help here.
> 


### No single entry point
Since there is no single entry point for services, it becomes challenging to log all service invocations, throttle them, implement unified transaction management strategy or a single point of validation. 

The traditional solution to the problem is to create a bunch of annotations and instrument the code via AOP:

```java
interface MemberPermissionService {
  @WrapInTransaction
  @Log
  @Validate
  @Throttle(max = 100)
  void grantPermission(String memberId, String permissionId);
  ...
}
```

The solution serves the purpose, but has significant limitations, though:

- What if we want to throttle invocations based on a dynamic parameter, instead of the hard-coded value of `100`? With annotations you can't do this. 
- How can we ensure that `@Throttle` annotation processor runs before `@WrapInTransaction` to avoid creating unnecessary transactions? Very likely, we'll have to introduce invisible dependency between `@WrapInTransaction` and `@Throttle` processors. Not good.

There must be a better way. Read on.


## Meet Commands / Reactions / Funnels (CRF)

CRF is a [command-oriented](https://martinfowler.com/bliki/CommandOrientedInterface.html) approach to service layer design, comprising of 3 main components – **Commands**, **Reactions** and **Funnels**. 

### A command
A command defines a single use case, an action that the user can perform. For example – `GrantPermission`, `RevokePermission` and `ListPermissions` will be our commands.

Technically, commands implement a marker interface. Since commands can return the *Response*, `R` generic defines a response type for the command:

```java
interface Command<T extends Command.R> {
  interface R {
    class Void implements R {
    }
  }
```

### A reaction
A reaction defines how the system reacts to a specific command. A reaction is where we write service code. For every command there must be a reaction. `GrantPermissionReaction`, `RevokePermissionReaction` and `ListPermissionsReaction` are our reactions. 

Technically, reactions derive from a single interface. The interface is generic and defines command type and the response type.

We also add a default method `commandType()` that resolves the matching command type via generics. [TypeToken](https://google.github.io/guava/releases/19.0/api/docs/com/google/common/reflect/TypeToken.html) comes from Guava library:

```java
interface Reaction<C extends Command<R>, R extends Command.R> {
  R react(C $);
	
  default TypeToken<C> commandType() {
    return new TypeToken<C>(getClass()) {};
  }    
}
```

### A funnel
All commands pass through a funnel. The funnel defines **how** the command will be executed – blocking, non-blocking or fire-or-forget. Naturally, it also contains code that runs for all commands (e.g. logging). 

The simplest systems have a single, synchronous funnel.

Below are interface examples of different funnels. Implementations will follow later:

#### Synchronous funnel

```java
interface Now {
  public <R extends Command.R, C extends Command<R>> R execute(C command);
}
```

#### Asynchronous funnel

```java
interface Future {
  public <R extends Command.R, C extends Command<R>> CompletableFuture<R> schedule(C command);
}
```

#### Reactive funnel

```java
interface Rx {
  public <R extends Command.R, C extends Command<R>>  Observable<R> observe(C command);
}
```

#### Durable fire-and-forget funnel

```java
interface Durable {
  <C extends Command> void enqueue(C command);
}
```

## Putting it all together

Let's start with a `GrantPermission` command that returns no result:

```java
class GrantPermission implements Command<Command.R.Void> {

  private final String memberId, permissionId;
    
  public GrantPermission(String memberId, String permissionId) { ... }
    
  public String memberId() {
    return memberId;
  }
    
  public String permissionId() {
    return permissionId;
  }
}
```

Then we implement a reaction. `Members` and `Permission` are parts of our domain model. The reaction is a Spring-managed component, so `Permissions` and `Members` dependencies are injected.

```java
@Component
class GrantPermissionReaction implements Reaction<GrantPermission, Command.R.Void> {

  private final Members members;
  private final Permissions permissions;
    
  public GrantPermissionReaction(Permissions permissions, Members members) { 
    ... 
  }
    
  @Override
  public Command.R.Void react(GrantPermissionCommand $) {
    Member member = members.byId($.memberId());
    Permission permission = permissions.byId($.permissionId());
    member.grantPermission(permission);
    return new Command.R.Void();
  }
}
```


We also have to implement a synchronous funnel. When a command is passed through the funnel (called `Now`), the funnel routes the command to the appropriate reaction. The reactions are resolved from Spring application context:

```java
interface Now {
  public <R extends Command.R, C extends Command<R>> R execute(C command);
}

@Component
class SimpleNow implements Now {

  private final ListableBeanFactory beanFactory;

  public Now(ListableBeanFactory beanFactory) {
    this.beanFactory = beanFactory;
  }

  public <R extends Command.R, C extends Command<R>> R execute(C command) {
    Class<? extends Command> commandType = command.getClass();
    Reaction<C, R> reaction = reactions()
                .stream()
                .filter(r -> r.commandType().isSupertypeOf(commandType))
                .findFirst()
                .orElseThrow(() -> new IllegalStateException("No reaction found for " + commandType));

    return reaction.react(command);
  }

  private Collection<Reaction> reactions() {
    return beanFactory.getBeansOfType(Reaction.class).values();
  }
}
```

The aforementioned example, however, asks Spring to provide all reactions every time a command passes through the funnel. This can hit the performance. Let's add [Caffeine](https://github.com/ben-manes/caffeine) caching to make sure that the funnel remembers which reaction corresponds to a command –

```java
@Component
class SimpleNow implements Now {

  private final LoadingCache<Type, Reaction> reactions;

  public Now(ListableBeanFactory beanFactory) {
    this.reactions = Caffeine.newBuilder()
            .build(commandType -> reactions(beanFactory)
             .stream()
             .filter(reaction -> reaction.commandType().isSupertypeOf(commandType))
             .findFirst()
             .orElseThrow(() -> new IllegalStateException("No reaction found for " + commandType);
  }

  public <R extends Command.R, C extends Command<R>> R execute(C command) {
    Reaction reaction = reactions.get(command.getClass());
    return (R) reaction.react(command);
  }
    
  private Collection<Reaction> reactions(ListableBeanFactory beanFactory) {
    return beanFactory.getBeansOfType(Reaction.class).values();
  }

}
```

Bingo! As we have glued all the components together, now we can look at the client code:

```java
class Application {

  @Autowired
  Now now;
  
  public void run(String memberId, String permissionId) {
    GrantPermission grantPermission = new GrantPermission(memberId, permissionId);
    now.execute(grantPermission);
  }
}
```

...if asynchronous funnel is used, it will look like this –

```java
class Application {
	
  @Autowired
  Future future;
  
  public void run(String memberId, String permissionId) {
    GrantPermission grantPermission = new GrantPermission(memberId, permissionId);
    future.schedule(grantPermission)
      .thenAccept(System.out::println)
      .thenAccept(...);
  }
}
```

...if RxJava funnel is used, it will look like this –

```java
class Application {

  @Autowired
  Rx rx;
	   
  public void run(String memberId, String permissionId) {
    GrantPermission grantPermission = new GrantPermission(memberId, permissionId);   
    rx.observe(grantPermission).subscribe(System.out::println);
  }
}
```

Amazing, isn't it?, The client can choose an appropriate funnel, depending on its requirements. 

### Command on steroids
Let's add a couple of default methods to `Command` interface, in order to make the client code sexier:

```java
interface Command<T extends Command.R> {

  default T execute(Now now) {
    return now.execute(this);
  }
    
  default CompletableFuture<T> schedule(Future future) {
    return future.schedule(this);
  }
    
  default Observable<T> observe(Rx rx) {
    return rx.observe(this);
  }
}
```

Now you can invoke commands in a natural way:

```
grantPermission.execute(now);

grantPermission.schedule(future);

grantPermission.observe(rx);
```


## Command composition
Commands are great because they can be composed (decorated). To demonstrate the idea, let's implement *retry* mechanism. If the commands fails with an exception, the system will retry it several times before bubbling up the exception.

We create a special `Try` command that can wrap any command:

```java
class Try<C extends Command<R>, R extends Command.R> implements Command<R> {

  private final C origin;
  private long times = 3;
    
  public Try(C origin) {
    this.origin = origin;
  }
    
  public Command<R> origin() {
    return origin;
  }
  
  public Try<C, R> times(long times) {
    this.times = times;
    return this;
  }
  
  public long times() {
    return times;
  }
}
```

Then we create a reaction. To implement retry, we use [SimpleRetryPolicy](http://docs.spring.io/spring-retry/docs/1.1.2.RELEASE/apidocs/org/springframework/retry/policy/SimpleRetryPolicy.html) class, that is part of [Sprint Retry](https://github.com/spring-projects/spring-retry) project.

```java
class TryReaction<C extends Command<R>, R extends Command.R>
                                          implements Reaction<Try<C, R>, R> {
  private final Router router;
    
  @Override
  public R react(Try<R> $) {
    SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
    retryPolicy.setMaxAttempts($.times());
    RetryTemplate template = new RetryTemplate();
    template.setRetryPolicy(retryPolicy);
        return template.execute(context -> {
            Command<R> origin = $.origin();
            Reaction<Command<R>, R> reaction = router.route(origin);
            return reaction.react(origin);
        });
  }
}
```

`TryReaction` depends on a new class called `Router` – a class that encapsulates command routing logic to reactions, that was previously part of `SimpleNow` funnel:

```java
@Component
class Router {
    
  private final LoadingCache<Type, Reaction> reactions;

  public Rounter(ListableBeanFactory beanFactory) {
    reactions = Caffeine.newBuilder()
                  .build(commandType -> reactions(beanFactory)
                      .stream()
                      .filter(reaction -> reaction.commandType().isSupertypeOf(commandType))
                      .findFirst()
                      .orElseThrow(() -> new IllegalStateException("No reaction found for " + commandType)));
    }

  private Collection<Reaction> reactions(ListableBeanFactory beanFactory) {
    return beanFactory.getBeansOfType(Reaction.class).values();
  }

  public <C extends Command<R>, R extends Command.R> Reaction<C, R> route(C command) {
    return reactions.get(command.getClass());
  }
}
```

Here is how the client code will look like: 

```java
new Try<>(
  new GrantPermission(...))
      .times(5)
      .execute(now);
```

I know you are amazed. I am too.

## Funnels on steroids

Let's enrich our funnel so all commands are logged and executed in a transaction.

Let's change our `SimpleNow` funnel. We will call it `PipedNow` in honour of *nix pipes:

```java
interface Now {
  public <R extends Command.R, C extends Command<R>> R execute(C command);
}

@Component
class PipedNow implements Now {
  public <R extends Command.R, C extends Command<R>> R execute(C command) {
    Now pipe = new Loggable(
	                 new Transactional(
			                new Reacting()));
    return pipe.execute(command);
  }
}
```

`Loggable`, `Transactional` are just plain old decorators. No magic:

```java
class Loggable implements Now {

  private final Logger log = LoggerFactory.getLogger(Loggable.class);
    
  private final Now origin;
    
  public Loggable(Now origin) {
    this.origin = origin;
  }
    
  @Override
  public <R extends Command.R, C extends Command<R>> R execute(C command) {
    log.info(">>> {}", command.toString());
    R response = origin.execute(command);
    log.info("<<< {}", response.toString());
    return response;
  }
}
```

```java
class Transactional implements Now {

  private final Now origin;
  private final TransactionTemplate tx;

  public Transactional(Now origin) {
    this.origin = origin;
    this.tx = new TransactionTemplate(txManager);
  }

  @Override
  public <R extends Command.R, C extends Command<R>> R execute(C command) {
    return tx.execute(txStatus -> origin.execute(command));
  }
}
```

```java
class Reacting implements Now {

  @Override
  public <R extends Command.R, C extends Command<R>> R execute(C command) {
    Reaction<C, R> reaction = router.route(command);
    return reaction.react(command);
  }
}
```

It's very easy to add new decorators. The best part of it is that decorators' execution order is explicitly visible in code. No magic.


## OK, what benefits did we get?
- Every use case is written in a separate class – less dependencies, testability is improved.
- Every use case passes through a single entry point – a *funnel*. This is very convenient for centralised validation, logging, transactional management, throttling, providing the [correlation identifier](http://www.enterpriseintegrationpatterns.com/patterns/messaging/CorrelationIdentifier.html). No AOP magic.
- Client can choose a command execution model by switching a funnel – sync, async, reactive, scheduled. You can even create a  mock funnel for testing.
- Service layer screams what the application is capable of doing:

```
net.blog.sizovs.services.GrantPermission

net.blog.sizovs.services.RevokePermission

net.blog.sizovs.services.ListPermissions
```

- You can add new parameters to the existing commands and response types w/o changing service signatures. 
- We got flexibility at command, reaction and funnel sides *almost* for free. As the system evolves, we can add more functionality to our service layer w/o large changes.

## Final words

CRF is a nice alternative to procedural service layer. I use it in most of the enterprise apps I build and it has proven to be extremely effective.

There is much more you can do with CRF. For example, command responses can be cached by holding results against a key synthesized from the command name and arguments. Or, you can have multiple versions of the same reaction and choose which one to execute depending on a context. Amazing!

The working code example can be [found on my GitHub](https://github.com/eduardsi/crf-demo). If you are interested in learning more about this approach – join my [Effective Java](http://devchampions.com/training/java/) class.