# Wrap Null

Should your code break because it lied ?

Because where you expected a value, you got a null ?

No, it should not.&#x20;

Null is a disease. In the worst situations, it can pretend to be an object but really isn't. Java is a notorious example.

<pre class="language-java"><code class="lang-java"><strong>public class Duration {
</strong>    public Duration add(Duration other) {
        return new Duration(this.seconds + other.seconds);
    }
}
</code></pre>

This code looks fine, but the devil is lurking in the shadows.&#x20;

Because Java will happily let anyone pass **null** to that **add** function.

Fortunately, there's a cure. Sort of.

```java
public class Duration {
    public Duration add(@NonNull Duration other) {
        return new Duration(this.seconds + other.seconds);
    }
}
```

Except it [doesn't really work](https://stackoverflow.com/a/34171296/8165144). It's, at best, a hint, at worst, just wasted text. The compiler won't prevent you from passing **null** to that method.

Now that the infection is spread, we have to resort to runtime checks.

```java
public class Duration {
    public Duration add(Duration other) {
        Objects.requireNonNull(other);
        return new Duration(this.seconds + other.seconds);
    }
}
```

And now these checks must spread through the code base, everywhere, again and again.

The gods are punishing our stupidity and we deserve it.

Is there any solution ? Sort of.&#x20;

**We can conventionally refuses Null to appear at some layer of our code.**

## Airlocking

<figure><img src="/files/zqj7Qd5Yx1SjQAIainr6" alt="" width="375"><figcaption><p>A regular 4-layer architecture</p></figcaption></figure>

You see, every program has a consistent structure : **a layered structure.**

There's the entry point of the program, the one users of the program use directly : **the Presentation Layer.**

There's the core of the program, dealing with business logic and manipulating our rich objects : **the Domain Layer.**

And there's a bridge connecting the two. In the Pragmatic Objects approach, we call it the [Service Layer](https://martinfowler.com/eaaCatalog/serviceLayer.html). *Some also call it the **UseCase Layer**.*

That Service layer contains what I like to call **an airlocking mechanism**. Whatever comes inside that layer is syntactically valid, and nulls are explicit. Thus, once we are in this layer, we can be assured that not a single undeclared **null** will appear.

That airlocking mechanism can be a simple function call before entering the service, or an automated middleware system using annotations.

In NestJS, I would use the following for example.

```typescript
type Props = {
  emailAddress: string;
  password: string;
};

export class LoginWithCredentialsCommand extends BaseCommand<Props> {
  validate(props: Props) {
    // This is our airlocking mechanism
    return {
      emailAddress: new WrappedString(props.emailAddress)
        .chain(new EmailAddress())
        .chain(new MaxLength(255))
        .expose(),
      password: new WrappedString(props.password)
        .chain(new MaxLength(255))
        .expose(),
    };
  }
}

@CommandHandler(LoginWithCredentialsCommand)
export class LoginWithCredentialsCommandHandler extends BaseCommandHandler<
  LoginWithCredentialsCommand,
  void
> {
  async execute(command: LoginWithCredentialsCommand): Promise<void> {}
}
```

By the time the command enter the handler's execute method, the input is sanitized.

So our Duration class shouldn't have to consider the case where the values given are nulls. We just have to assume they won't ever be and **let our Airlocking system protect it.**

```java
public class Duration {
    public Duration add(Duration other) {
        return new Duration(this.seconds + other.seconds);
    }
}

public class AddDurationCommandHandler {
    public Duration execute(Duration a, Duration b) {
        Objects.requireNonNull(a);
        Objects.requireNonNull(b);
        
        return a.add(b);
    }
}
```

However, some code inside that Service layer may (will) call other services from the outside world such as a database or an external API, **which can give us nullables.**

The best way to deal with these nullables is to acknowledge their existence and transform them into an actually useful construct : Optionals.

## Optional

The concept is directly borrowed (shamelessly stolen) from the functional programming concept of [Maybe monad](https://www.futurelearn.com/info/courses/functional-programming-haskell/0/steps/27247).&#x20;

It's a simple object : either it has a value, or it doesn't.&#x20;

In practice, we rarely have the occasion of wrapping inputs into Optionals. If we receive JSON, for example, we can directly receive nulls, so we can make null checks directly.

But when fetching an entity from the database, it's useful to have a type that allows us to return a value if it exists, or the absence of value if it doesn't. But we shouldn't trick the client of that function call into believing they will always receive a value.&#x20;

So we should make it explicit by using an Optional.

```java
interface IUserRepository {
    Optional<User> byId(String id);
}

class GetUserByIdCommandHandler {
    User execute(String id) {
        Optional<User> user = this.userRepository.byId(id);
        return user.orElseThrow(() -> new RuntimeException("no user found"));
    }
}
    
```

This way, clients can either directly throw an error in the absence of the value, or take specific actions. But in both case, it's made explicit.

And the bonus : we get a proper "absence of value" mechanism. One that doesn't throw unexpectedly.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.pragmatic-objects.com/practices/wrap-null.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
