Built in services

The framework provides some built-in services you can inject by type in components and actions out of the box.

Here is the list:

Type Description

org.talend.sdk.component.api.service.cache.LocalCache

Provides a small abstraction to cache data which don’t need to be recomputed very often. Commonly used by actions for the UI interactions.

org.talend.sdk.component.api.service.dependency.Resolver

Allows to resolve a dependency from its Maven coordinates.

javax.json.bind.Jsonb

A JSON-B instance. If your model is static and you don’t want to handle the serialization manually using JSON-P you can inject that instance.

javax.json.spi.JsonProvider

A JSON-P instance. Prefer other JSON-P instances if you don’t exactly know why you use this one.

javax.json.JsonBuilderFactory

A JSON-P instance. It is recommended to use this one instead of a custom one for memory/speed optimizations.

javax.json.JsonWriterFactory

A JSON-P instance. It is recommended to use this one instead of a custom one for memory/speed optimizations.

javax.json.JsonReaderFactory

A JSON-P instance. It is recommended to use this one instead of a custom one for memory/speed optimizations.

javax.json.stream.JsonParserFactory

A JSON-P instance. It is recommended to use this one instead of a custom one for memory/speed optimizations.

javax.json.stream.JsonGeneratorFactory

A JSON-P instance. It is recommended to use this one instead of a custom one for memory/speed optimizations.

org.talend.sdk.component.api.service.configuration.LocalConfiguration

Represents the local configuration which can be used during the design.

it is not recommended to use it for the runtime since the local configuration is generally different and the instances are distincts.
you can also use the local cache as an interceptor with @Cached

Every interface that extends HttpClient and that contains methods annotated with @Request

This let you define an http client in a declarative manner using an annotated interface.

See the HttpClient usage for details.
all these injected instances are serializable which is important for the big data environment, if you create the instances yourself you will not benefit from that features and the memory optimization done by the runtime so try to prefer to reuse the framework instances over custom ones.

HttpClient usage

Let assume that we have a REST API defined like below, and that it requires a basic authentication header.

GET /api/records/{id}

-

POST /api/records

with a json playload to be created {"id":"some id", "data":"some data"}

To create an http client able to consume this REST API, we will define an interface that extends HttpClient,

The HttpClient interface lets you set the base for the http address that our client will hit.

The base is the part of the address that we will need to add to the request path to hit the api.

Every method annotated with @Request of our interface will define an http request. Also every request can have @Codec that let us encode/decode the request/response playloads.

if your payload(s) is(are) String or Void you can ignore the coder/decoder.
public interface APIClient extends HttpClient {
    @Request(path = "api/records/{id}", method = "GET")
    @Codec(decoder = RecordDecoder.class) //decoder =  decode returned data to Record class
    Record getRecord(@Header("Authorization") String basicAuth, @Path("id") int id);

    @Request(path = "api/records", method = "POST")
    @Codec(encoder = RecordEncoder.class, decoder = RecordDecoder.class) //encoder = encode record to fit request format (json in this example)
    Record createRecord(@Header("Authorization") String basicAuth, Record record);
}
The interface should extends HttpClient.

In the codec classes (class that implement Encoder/Decoder) you can inject any of your services annotated with @Service or @Internationalized into the constructor. The i18n services can be useful to have i18n messages for errors handling for example.

This interface can be injected into our Components classes or Services to consume the defined api.

@Service
public class MyService {

    private APIClient client;

    public MyService(...,APIClient client){
        //...
        this.client = client;
        client.base("http://localhost:8080");// init the base of the api, ofen in a PostConstruct or init method
    }

    //...
    // Our get request
    Record rec =  client.getRecord("Basic MLFKG?VKFJ", 100);

    //...
    // Our post request
    Record newRecord = client.createRecord("Basic MLFKG?VKFJ", new Record());
}

Note: by default /+json are mapped to JSON-P and /+xml to JAX-B if the model has a @XmlRootElement annotation.

Advanced HTTP client request customization

For advanced cases you can customize the Connection directly using @UseConfigurer on the method. It will call your custom instance of Configurer. Note that you can use some @ConfigurerOption in the method signature to pass some configurer configuration.

For instance if you have this configurer:

public class BasicConfigurer implements Configurer {
    @Override
    public void configure(final Connection connection, final ConfigurerConfiguration configuration) {
        final String user = configuration.get("username", String.class);
        final String pwd = configuration.get("password", String.class);
        connection.withHeader(
            "Authorization",
            Base64.getEncoder().encodeToString((user + ':' + pwd).getBytes(StandardCharsets.UTF_8)));
    }
}

You can then set it on a method to automatically add the basic header with this kind of API usage:

public interface APIClient extends HttpClient {
    @Request(path = "...")
    @UseConfigurer(BasicConfigurer.class)
    Record findRecord(@ConfigurerOption("username") String user, @ConfigurerOption("password") String pwd);
}
Scroll to top