Business Code

Now it is time to spice up our «Hello World» application with some business code. With SeedStack business framework, it is easy to write clean and maintainable business code.

Domain-Driven Design

Domain-Driven Design is a software approach built on the idea of solving business problems through code. This is done by focusing on the heart of the business logic, to distill a design that can solve business problems.

The business framework helps with the implementation of that domain model. It also provides default implementations and helpers to quickly address related needs like model mapping or pagination.

But keep in mind that it’s up to you to provide a proper model for the business problems you’re solving.

Read more about the Domain-Driven Design on the DDD basics page.

A trivial domain

We don’t want to go into the details of Domain-Driven Design yet, so we will use a trivial domain model with a single aggregate.

Hello World model

Although it is simple, you can already see that:

  • The PersonId class is a value object that is used as an identifier.
  • The Person class is an entity that act as the root of the person aggregate.
  • A changeName() business-meaningful method is preferred over setters.
  • A package materializes the boundary of the person aggregate.

The person aggregate

In the domain.model package, create a sub-package named person. In this sub-package create the PersonId value object:

package org.generated.project.domain.model.person;

import org.seedstack.business.domain.BaseValueObject;

public class PersonId extends BaseValueObject {
    private final String email;

    public PersonId(String email) {
        this.email = email;
    }

    public String getEmail() {
        return email;
    }
}

Then, in the same package, create the Person aggregate root entity:

package org.generated.project.domain.model.person;
 
import org.seedstack.business.domain.BaseAggregateRoot;
 
public class Person extends BaseAggregateRoot<PersonId> {
    private final PersonId id;
    private String firstName;
    private String lastName;
 
    public Person(PersonId id) {
        this.id = id;
    }
 
    @Override
    public PersonId getId() {
        return id;
    }
 
    public String getFirstName() {
        return firstName;
    }
 
    public String getLastName() {
        return lastName;
    }
 
    public void changeName(String firstName, String lastName) {
        if (firstName == null || firstName.isEmpty()) {
            throw new IllegalArgumentException("First name is missing");
        }
        if (lastName == null || lastName.isEmpty()) {
            throw new IllegalArgumentException("Last name is missing");
        }
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

The greeter service

We will now create a service that greets a person. In the domain.services package, create the Greeter service interface:

package org.generated.project.domain.services;

import org.generated.project.domain.model.person.Person;
import org.seedstack.business.Service;

@Service
public interface GreeterService {
    String greet(Person person);
}

Then, in the same package, create the DefaultGreeterService implementation:

package org.generated.project.domain.services;

import org.generated.project.domain.model.person.Person;

public class DefaultGreeterService implements GreeterService {
    @Override
    public String greet(Person person) {
        return String.format(
                "Hello %s %s!",
                person.getFirstName(),
                person.getLastName()
        );
    }
}

We can now inject this service in the HelloResource class to move the business logic away:

package org.generated.project.interfaces.rest;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.generated.project.domain.model.person.Person;
import org.generated.project.domain.model.person.PersonId;
import org.generated.project.domain.services.GreeterService;

@Path("hello")
public class HelloResource {
    @Inject
    private GreeterService greeterService;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        Person person = new Person(new PersonId("someone@some.org"));
        person.changeName("Robert", "SMITH");
        return greeterService.greet(person);
    }
}

Now what ?

On this page you have learned:

  • That Domain-Driven Design is a software approach focused on solving business problems,
  • How to write a very simple domain model,
  • How to write a very simple service.

Troubleshooting

If you can’t get this to work, check the troubleshooting page.

Next step

If you want to learn more, continue on the tutorial to learn about persistence.

   

On this page


Edit