Getting started

The Kalix development tools help you to get started quickly. They include:

  • A Maven archetype that generates the recommended project structure. The generated project is a regular Spring Boot project with a few configurations to integrate it seamlessly with Kalix.

  • A Maven plugin to help you deploy your application to Kalix.

The generated project also contains configuration for packaging and deploying the service.

Prerequisites

Before you start, make sure you have the following:

  • JDK 17 or later

  • Apache Maven 3.6 or later

  • Docker 20.10.14 or higher (to run locally)

To deploy the Kalix service, you need:

1. Generate and build the Kalix project

The Maven archetype template prompts you to specify the project’s group ID, name and version interactively. Run it using the commands shown for your OS.

In IntelliJ, you can skip the command line. Open the IDE, select File > New > Project, and click to activate Create from archetype. Use the UI to locate the archetype and fill in the blanks.

Follow these steps to generate and build your project:

  1. From a command window, run the template in a convenient location:

    Linux or macOS
    mvn archetype:generate \
      -DarchetypeGroupId=io.kalix \
      -DarchetypeArtifactId=kalix-spring-boot-archetype \
      -DarchetypeVersion=1.4.1
    Windows 10+
    mvn archetype:generate ^
      -DarchetypeGroupId=io.kalix ^
      -DarchetypeArtifactId=kalix-spring-boot-archetype ^
      -DarchetypeVersion=1.4.1
  2. Navigate to the new project directory.

  3. Open it on your preferred IDE / Editor.

2. Examine the project

The initial project contains a Main class for a Spring Boot application. The application is already configured to wire and register all Kalix components it finds in the classpath.

src/main/java/com/example/Main.java
@SpringBootApplication (1)
public class Main {

  private static final Logger logger = LoggerFactory.getLogger(Main.class);

  public static void main(String[] args) {
    logger.info("Starting Kalix Application");
    SpringApplication.run(Main.class, args); (2)
  }
}
1 Main class is annotated with @SpringBootApplication.
2 The application is started like any other Spring Boot application.

3. Implementing first component

Kalix have different kinds of components that you can use to implement your application. The list of components are:

For this Getting started walk-through, we will implement a Counter based on a Value Entity. It’s a simple counter that receives commands to increase the counter.

src/main/java/com/example/CounterEntity.java
@TypeId("counter") (1)
@Id("counter_id") (2)
public class CounterEntity extends ValueEntity<Integer> { (3)

  @Override
  public Integer emptyState() { return 0; } (4)
  @PostMapping("/counter/{counter_id}/increase") (5)
  public Effect<Number> increaseBy(@RequestBody Number increaseBy) {
    int newCounter = currentState() + increaseBy.value(); (6)
    return effects()
        .updateState(newCounter) (7)
        .thenReply(new Number(newCounter));
  }

}
1 Every Entity must be annotated with @TypeId with a stable identifier. This identifier should be unique among the different existing entities within a Kalix application.
2 The @Id value should be unique per entity and map to some field being received on the route path, in this example it’s the counter_id.
3 The CounterEntity class should extend kalix.javasdk.valueentity.ValueEntity.
4 The initial state of each counter is defined as 0.
5 The method is accessible as a POST endpoint on /counter/{counter_id}/increase, where counter_id will be its unique identifier. Note that it matches the @Id value.
6 Its increaseBy method receives a Number as input and increases the counter by adding it to the current state.
7 Finally, using the Effect API, we instruct Kalix to persist the new state, and we build a reply.

The Number record in this example is used as input for the increaseBy method and as to return the counter’s current state.

src/main/java/com/example/Number.java
package com.example;

public record Number(Integer value) {}
A Kalix component doesn’t require any other annotation. They will be registered to Kalix and be exposed automatically. It suffices to add them on the same package or on a sub-package of your Main class. Please, refer to Dependency injection page for more details on how Kalix components integrates with Spring’s application context.

The project also includes a dependency on the Kalix Java SDK Test Kit. Please consult the component specific pages to learn more about writing unit tests and integration tests for your application.

4. Package service

The project is configured to package your service into a Docker image which can be deployed to Kalix. The Docker image name can be changed in the pom.xml file’s properties section. Update this file to publish your image to your Docker repository.

This uses JDK 17 and the image is based on the Eclipse Adoptium JDK image (formerly Adopt OpenJDK). Choose a different image in the docker-maven-plugin configuration pom.xml file.

mvn install

5. Run locally

To start your service locally, run:

mvn kalix:runAll

This command will start your Kalix service and a companion Kalix Runtime as configured in docker-compose.yml file.

If you prefer, you can also start docker-compose directly by running docker-compose up in one terminal and in another terminal start your Kalix service with:

mvn kalix:run

With both the runtime and your service running, any defined endpoints should be available at localhost:9000, the runtime local address.

curl -XPOST -H "Content-Type: application/json" localhost:9000/counter/foo/increase -d '{ "value": 10 }'

6. Deploy to Kalix

To deploy your service to Kalix:

First make sure you have updated the dockerImage property in the pom.xml to point at your Docker registry. Then use the deploy target to build the container image, publish it to the container registry as configured in the pom.xml file, and the target kalix:deploy to automatically deploy the service to Kalix:

mvn deploy kalix:deploy
If you time stamp your image. For example, <dockerTag>${project.version}-${build.timestamp}</dockerTag> you must always run both targets in one pass, i.e. mvn deploy kalix:deploy. You cannot run mvn deploy first and then mvn kalix:deploy because they will have different timestamps and thus different `dockerTag`s. This makes it impossible to reference the image in the repository from the second target.
  • When using the CLI, in your command window, you can set your Kalix project to be the current project:

    kalix config set project <project-name>
  • Deploy your service following the instructions at Development Process - Deploy to Kalix.