Skip to content

Stork Programmatic API#

Stork proposes a programmatic API that lets you register new service Definitions and do manual lookup and selection. When using the programmatic API of Stork, you can: Retrieve the singleton Stork instance. This instance is configured with the set of Services it manages. Register new service definition. Retrieve the Service you want to use. Each Service is associated with a name. Retrieve the ServiceInstance, which will provide the metadata to access the actual instance.

Initializing Stork#

If your framework does not already provide a configured Stork instance, you need to do:

package examples;

import io.smallrye.stork.Stork;
import io.smallrye.stork.api.ServiceDefinition;
import io.smallrye.stork.api.ServiceInstance;
import io.smallrye.stork.loadbalancer.random.RandomConfiguration;
import io.smallrye.stork.servicediscovery.staticlist.StaticConfiguration;

import java.time.Duration;

public class InitializationExample {

    public static void main(String[] args) {
        Stork.initialize();
        Stork stork = Stork.getInstance();
        // ...
    }
}

Adding service dynamically#

To register a new ServiceDefinition, use the defineIfAbsent method:

package examples;

import io.smallrye.stork.Stork;
import io.smallrye.stork.api.ServiceDefinition;
import io.smallrye.stork.loadbalancer.random.RandomConfiguration;
import io.smallrye.stork.servicediscovery.staticlist.StaticConfiguration;

public class DefinitionExample {

    public static void example(Stork stork) {
        String example = "localhost:8080, localhost:8081";

        // A service using a static list of locations as discovery
        // As not set, it defaults to round-robin to select the instance.
        stork.defineIfAbsent("my-service",
                ServiceDefinition.of(new StaticConfiguration().withAddressList(example)));

        // Another service using the random selection strategy, instead of round-robin
        stork.defineIfAbsent("my-second-service",
                ServiceDefinition.of(new StaticConfiguration().withAddressList(example),
                        new RandomConfiguration()));
    }
}

The ServiceDefinition instances can be created from:

  • A service discovery configuration - these classes are provided by the service discovery implementations,
  • An optional load balancer configuration - these classes are provided by the load balancer implementations

Attributes from the service discovery and load balancer can be configured from the Configuration classes.

Looking for service instances#

To list the service instances for a given service, or to select an instance according to the load balancer strategy, use the following code:

package examples;

import io.smallrye.mutiny.Uni;
import io.smallrye.stork.Stork;
import io.smallrye.stork.api.Service;
import io.smallrye.stork.api.ServiceDefinition;
import io.smallrye.stork.api.ServiceInstance;
import io.smallrye.stork.loadbalancer.random.RandomConfiguration;
import io.smallrye.stork.servicediscovery.staticlist.StaticConfiguration;

import java.util.List;
import java.util.Map;

public class LookupExample {

    public static void example(Stork stork) {
        Service service = stork.getService("my-service");

        // Gets all the available instances:
        Uni<List<ServiceInstance>> instances = service.getInstances();
        // Select one instance using the load balancing strategy
        Uni<ServiceInstance> instance = service.selectInstance();

        // Gets all the managed services:
        Map<String, Service> services = stork.getServices();
    }
}

The lookup and selection methods are returning Uni as these processes are asynchronous.

All in one example#

The following snippet provides an all in one example of the Stork programmatic API:

package examples;

import io.smallrye.stork.Stork;
import io.smallrye.stork.api.ServiceDefinition;
import io.smallrye.stork.api.ServiceInstance;
import io.smallrye.stork.loadbalancer.random.RandomConfiguration;
import io.smallrye.stork.servicediscovery.staticlist.StaticConfiguration;

import java.time.Duration;

public class StorkApiExample {

    public static void main(String[] args) {
        Stork.initialize();
        Stork stork = Stork.getInstance();

        String example = "localhost:8080, localhost:8082";

        // A service using a static list of locations as discovery
        // As not set, it defaults to round-robin to select the instance.
        stork.defineIfAbsent("my-service",
                ServiceDefinition.of(new StaticConfiguration().withAddressList(example)));

        // Another service using the random selection strategy, instead of round-robin
        stork.defineIfAbsent("my-second-service",
                ServiceDefinition.of(new StaticConfiguration().withAddressList(example),
                        new RandomConfiguration()));

        ServiceInstance instance = stork.getService("my-second-service").selectInstance()
                .await().atMost(Duration.ofSeconds(1));
        System.out.println(instance.getHost() + ":" + instance.getPort());
    }
}