§Getting started with Lagom in Maven
This page shows how to create and run your first Lagom project.
§Creating a new Lagom project
A Lagom system is typically made up of a set of maven projects, each build providing multiple services. The easiest way to get started with a new Lagom system is to create a new project using the Maven archetype plugin, with the Lagom Maven archetype:
$ mvn archetype:generate -DarchetypeGroupId=com.lightbend.lagom \
-DarchetypeArtifactId=maven-archetype-lagom-java -DarchetypeVersion=1.2.0
Note: Ensure you replace the 1.2.0 archetype version with the latest version of Lagom.
This will prompt you for a groupId
, artifactId
and version
. You might choose, for example, com.example
as a groupId
, and my-first-system
for an artifactId
. Once you’ve followed the prompts, it will create a new system with two services in it: hello
and stream
.
§Anatomy of a Lagom project
The created project contains the following elements:
my-first-system → Project root
└ hello-api → hello world api project
└ hello-impl → hello world implementation project
└ stream-api → stream api project
└ stream-impl → stream implementation project
└ integration-tests → Integration tests
└ pom.xml → Project root build file
Notice how each service is broken up into two projects: api and implementation. The api project contains a service interface through which consumers may interact with the service. While the implementation project contains the actual service implementation.
§Understanding services projects
- The service interface is always placed in the api project. For instance, the service interface for the
hello
service can be found in thehello-api
project (look for theHelloService.java
source file).
public interface HelloService extends Service {
ServiceCall<NotUsed, String> hello(String id);
@Override
default Descriptor descriptor() {
return named("helloservice").withCalls(
restCall(Method.GET, "/api/hello/:id", this::hello)
).withAutoAcl(true);
}
}
-
The service interface needs to inherit from
Service
and provide an implementation ofService#descriptor
method. -
The implementation of
Service#descriptor
returns aDescriptor
. ADescriptor
defines the service name and the REST endpoints offered by a service. For each declared endpoint, an abstract method is declared in the service interface, e.g., see theHelloService#hello
method. -
The implementation of the service abstract methods is provided by the related implementation project. For instance, the service implementation of the
HelloService#hello
method, for thehello
service, can be found in thehello-impl
project (look for theHelloServiceImpl.java
source file).
public class HelloServiceImpl implements HelloService {
private final PersistentEntityRegistry persistentEntityRegistry;
@Inject
public HelloServiceImpl(PersistentEntityRegistry persistentEntityRegistry) {
this.persistentEntityRegistry = persistentEntityRegistry;
persistentEntityRegistry.register(HelloWorld.class);
}
@Override
public ServiceCall<NotUsed, String> hello(String id) {
return request -> {
// Look up the hello world entity for the given ID.
PersistentEntityRef<HelloCommand> ref = persistentEntityRegistry.refFor(HelloWorld.class, id);
// Ask the entity the Hello command.
return ref.ask(new Hello(id, Optional.empty()));
};
}
}
- The
PersistentEntityRegistry
allows to persist data in the database using Event Sourcing and CQRS.
§Running Lagom services
Lagom includes a development environment that let you start all your services by invoking the runAll
task on the Lagom maven plugin. Open the terminal and cd
to your Lagom project (some log output cut for brevity):
$ cd my-first-system
$ mvn lagom:runAll
...
[info] Starting embedded Cassandra server
..........
[info] Cassandra server running at 127.0.0.1:4000
[info] Service locator is running at http://localhost:8000
[info] Service gateway is running at http://localhost:9000
...
[info] Service helloworld-impl listening for HTTP on 0:0:0:0:0:0:0:0:24266
[info] Service hellostream-impl listening for HTTP on 0:0:0:0:0:0:0:0:26230
(Services started, press enter to stop and go back to the console...)
You can verify that the services are indeed up and running by invoking one of its endpoints, e.g:
$ curl http://localhost:9000/api/hello/World
And you should get back the message Hello, World!
.
If you are wondering why we have created two services in the seed template, instead of having just one, the reason is simply that (quoting Jonas Bonér):
One microservice is no microservice - they come in systems.
Said otherwise, we believe you will be creating several services, and we felt it was important to showcase intra-service communication.