Add to existing project

Take a Java service that already posts webhooks by hand and move one ad-hoc HTTP call onto a generated, type-safe Repost sender in about 15 minutes.

You already have a service that posts webhooks to your customers with HttpClient and a hand-built JSON body. This guide replaces one of those calls with a generated, type-safe sender: no rewrite, no big bang. Set aside about 15 minutes.

You start from something like this, scattered wherever an event happens:

// The ad-hoc send you have today.
HttpRequest request = HttpRequest.newBuilder(URI.create(customer.webhookUrl()))
    .header("content-type", "application/json")
    .POST(BodyPublishers.ofString("{\"type\":\"order.created\",\"data\":{\"id\":\"" + order.id() + "\"}}"))
    .build();
httpClient.send(request, BodyHandlers.discarding());

The runtime is published to Maven Central under sh.repost and is server-side only: it holds a publish credential.

The published runtime is version 1.0.18 and the schema engine is 0.9.0. Kotlin projects should follow the Kotlin guide instead.

1
Add the plugin and BOM

Import the repost-bom to keep every Repost artifact on one version, depend on repost-client, and add the repost-maven-plugin to generate on every build.

<properties>
  <maven.compiler.release>11</maven.compiler.release>
  <repost.version>1.0.18</repost.version>
</properties>
 
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>sh.repost</groupId>
      <artifactId>repost-bom</artifactId>
      <version>${repost.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
 
<dependencies>
  <dependency>
    <groupId>sh.repost</groupId>
    <artifactId>repost-client</artifactId>
  </dependency>
</dependencies>
 
<build>
  <plugins>
    <plugin>
      <groupId>sh.repost</groupId>
      <artifactId>repost-maven-plugin</artifactId>
      <version>${repost.version}</version>
      <configuration>
        <generators><generator>javaSdk</generator></generators>
      </configuration>
      <executions>
        <execution>
          <goals><goal>generate</goal></goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

The plugin adds no transitive HTTP, JSON, or logging libraries to your classpath, so it cannot collide with your own Jackson, SLF4J, or OkHttp versions.

2
Initialize a schema in your repo

From the repository root:

repost schema init --language java --output ./src/main/java

This scaffolds a repost/ directory. Model the event you already send with a Java generator block:

generator javaSdk {
  language       = "java"
  output         = "../target/generated-sources/repost"
  resourceOutput = "../target/generated-resources/repost"
  packageName    = "com.example.repost"
  clientName     = "RepostClient"
}
 
model Order {
  id String
}
 
type Order {
  created
}
 
event OrderCreated {
  type      @type(Order.created)
  data      Order
  timestamp DateTime
}

Add one field per key you send today. Code generation explains the four extra generator fields.

3
Generate the client

The plugin binds to the generate-sources phase, so a normal compile already produces your client. To run generation on its own:

./mvnw repost:generate
4
Connect an environment

Create an environment in the dashboard, copy its publish API key into your environment, then deploy your schema:

repost auth login
repost schema migrate deploy

Replace the ad-hoc call

Swap the raw HttpClient send for the generated sender. Repost fans the event out to the customer's registered endpoints, so you no longer track webhookUrl yourself. The client is AutoCloseable; create() reads the credential and endpoint from the environment:

Order order = Order.builder().id("order-123").build();
try (RepostClient repost = RepostClient.create()) {
    SendResult sync = repost.webhooks().order().created("customer-123", order);
    System.out.println(sync.getId());
 
    SendResult async = repost.webhooks().order().createdAsync(
                    "customer-123",
                    order,
                    SendOptions.builder().idempotencyKey("order-123").build())
            .toCompletableFuture()
            .join();
    System.out.println(async.getId());
}

A successful send returns a SendResult whose getDeliveryState() is ACCEPTED; any failure throws a RepostException subclass. Always close a client you created.

Verify delivery

Trigger the code path that fires the event, then open the dashboard. The send appears in the event stream with its msg_... id and per-endpoint delivery status. Once you trust it, delete the old HttpClient call and repeat for the next event type.

Continue