Skip to content

Java SDK for communicating with the Courier REST API.

License

Notifications You must be signed in to change notification settings

trycourier/courier-java

Repository files navigation

Courier Java Library

Maven Central fern shield

This is the official Java library for sending notifications with the Courier REST API.

Documentation

For a full description of request and response payloads and properties, please see the official Courier API docs.

Requirements

This library requires Java 11+.

Installation

Gradle

Add the dependency in your build.gradle:

dependencies {
    implementation 'com.courier:courier-java:x.x.x'
}

Maven

Add the dependency in your pom.xml:

<dependency>
    <groupId>com.courier</groupId>
    <artifactId>courier-java</artifactId>
    <version>0.x.x</version>
</dependency>

Usage

Below is an example of how to instantiate the Courier client and send a message.

import com.courier.api.Courier;

Courier courier = Courier.builder()
    .authorizationToken("YOUR_TOKEN") # Defaults to System.getenv("COURIER_AUTHORIZATION_TOKEN")    
    .build();

courier.send(SendMessageRequest.builder()
    .message(Message.of(TemplateMessage.builder()
        .template("<COURIER_TEMPLATE>")
        .to(MessageRecipient.of(Recipient.of(UserRecipient.builder()
            .email("[email protected]")
            .build())))
        .build()))
    .build());

Upgrade Guides

v2 to v3

v3 of our SDK is automatically generated by Fern. v3 comes with several improvements that we describe below:

  • Resource-scoped SDK methods: Endpoints are scoped under their resource. For example, instead of courier.deleteBrands the SDK now reads courier.brands.delete(...)
  • Docs on Hover: All endpoint and parameter level documentation that you see on our docs website is now embedded directly within the SDKs.
  • Retries with exponential backoff: The SDK will automatically retry failures with exponential backoff.
  • Strongly Typed: The SDK has Java objects to describe each of our request and response models. Each object has a static builder method and uses the staged builder pattern.
    UserRecipient.builder()
        .email("[email protected]")
        .build(); 
  • Unions The SDK has natively supports unions. Every union is modelled as a java class that has static factory methods.
    // Message has static factory methods that either take a TemplateMessage or 
    // ContentMessage
    Message.of(TemplateMessage.builder()...)
    
    Message.of(ContentMessage.builder()...)

Request Options

Every endpoint has an overloaded equivalent which takes RequestOptions that allow you to override settings for that particular request.

import com.courier.api.Courier;

courier.brands.get(..., RequestOptions.builder()
    .authorizationToken(...)
    .build())

Idempotency Headers

You can specify idempotency headers by providing an IdempotentRequestOptions parameter.

import com.courier.api.Courier;
import java.util.UUID;

courier.send(..., IdempotentRequestOptions.builder()
    .idempotencyKey(UUID.randomUUID().toString())
    .build())

Exception Handling

All errors thrown by the SDK will be subclasses of com.courier.api.APIError.

import com.courier.api.core.ApiError;

try {
    courier.brands.get(...)
} catch (ApiError e) {
    System.out.println(e.statusCode());
    System.out.println(e.body());
}

Retries

409 Conflict, 429 Rate Limit, and >=500 Internal errors will all be retried twice with exponential backoff.

Additional Properties

Sometimes, the server response may include additional properties that are not available in the SDK. Use the getAdditionalProperties() method to access them.

Object value = entity.getAdditionalProperties().get("new_prop");

Contributing

While we value open-source contributions to this SDK, this library is generated programmatically. Additions made directly to this library would have to be moved over to our generation code, otherwise they would be overwritten upon the next generated release. Feel free to open a PR as a proof of concept, but know that we will not be able to merge it as-is. We suggest opening an issue first to discuss with us!

On the other hand, contributions to the README are always very welcome!