Creating DSL-like API's in Java (and fixing Builder pattern)
Tags: java, lang
Published: 2019-11-05 13:33:44

---
title: Creating DSL-like API's in Java (and fixing Builder pattern)
published: true
description: Assembling line for complex constructions
tags: #java #lang
---

In many cases Java DSL is just an way to assemble some complex configuration and then pass built structure to internal method which will handle it. For example, SQL query builders, HTTP request builders are all fall into this category. 

First of all, plain `Builder` pattern rarely convenient in such cases. It has no restrictions on order of calls and may result to incomplete configuration or just unreadable code. 

The solution is to split `Builder` into set of interface chaining each other.

To illustrate approach let's imagine that we're trying to write yet another, very simple HTTP request builder. With described approach it might look like this:

```java
public interface RequestBuilder {
    static Stage1 get(String uri) {
        return new Builder(Method.GET, uri, list());
    }

    interface Stage1 {
        default Stage2 withoutParameters(Object... parameters) {
            return with();
        }

        Stage2 with(Object... parameters);
    }

    interface Stage2 {
        Request build();
    }

    class Builder implements Stage1, Stage2 {
        private final Method method;
        private final String uri;
        private final List<?> parameters;

        private Builder(final Method method, final String uri, final List<?> parameters) {
            this.method = method;
            this.uri = uri;
            this.parameters = parameters;
        }

        @Override
        public Stage2 with(final Object... parameters) {
            return new Builder(method, uri, list(parameters));
        }

        @Override
        public Request build() {
            return new Request(method, uri, parameters);
        }
    }
}
```
The building code is concentrated in `Builder` class. This implementation uses immutable instance, but this is not strictly necessary. 

The whole `Builder` class is never exposed directly to user code. Instead we return interface which limits user actions to `with()` and `withoutParameters()`. These methods in turn return next building stage interface (`Stage2`) which allows user to finish building object.

The usage of the example code might look like below. 
Note that there is no way to __not__ specify parameters (or lack of them) explicitly:
```java
...
RequestBuilder.get("http://somewhere.com/api/users/{param1}")
              .with(userId1)
              .build();
...
RequestBuilder.get("http://somewhere.com/api/users")
              .withoutParameters()
              .build();
...

```
The example is quite simple, but actually there might be any number of intermediate stages and they not necessarily should fix building process as unidirectional graph (for example, creating loops to assemble complex sub-object can be easily done as well).

What we get in turn:
- There is no way to build incomplete object
- User is guided through object building stages by IDE and limited number of choices at each step
- All invocations through the code follow same pattern, making reading and reviewing such a code simpler
- Whole API being properly designed and named can form quite convenient to use DSL.