Terug naar blog
Maven coordinates for the PolyLingo Java SDK alongside a short Java client setup snippet.

Vertaal gestructureerde inhoud uit Java met de PolyLingo SDK

By Robert

Gestructureerde inhoud vertalen vanuit Java met de PolyLingo SDK

De PolyLingo Java SDK is nu beschikbaar op Maven Central. Het dekt de volledige PolyLingo API: synchrone vertaling, batchverzoeken, async jobs met polling, en alle utility endpoints. Het vereist Java 11 of hoger, gebruikt de standaard bibliotheek HTTP-client, en heeft precies één runtime-afhankelijkheid: Jackson voor JSON.


Installatie

Maven

<dependency>
  <groupId>com.usepolylingo</groupId>
  <artifactId>polylingo</artifactId>
  <version>0.1.0</version>
</dependency>

Gradle

implementation 'com.usepolylingo:polylingo:0.1.0'

Geen extra HTTP-client afhankelijkheid vereist. De SDK gebruikt java.net.http.HttpClient uit de Java 11 standaardbibliotheek.


De client instellen

import com.usepolylingo.polylingo.PolyLingo;
 
PolyLingo client = PolyLingo.builder()
    .apiKey(System.getenv("POLYLINGO_API_KEY"))
    .build();

Twee optionele builder parameters zijn beschikbaar:

PolyLingo client = PolyLingo.builder()
    .apiKey(System.getenv("POLYLINGO_API_KEY"))
    .baseUrl("https://api.usepolylingo.com/v1") // standaard, overschrijven voor zelf-gehoste instanties
    .timeout(Duration.ofSeconds(30))            // standaard is 120 seconden
    .build();

Bewaar je API-sleutel in een omgevingsvariabele. Nooit hardcoderen of committen naar versiebeheer.

De SDK gebruikt overal het builder-patroon. Geen positionele constructors, geen verplichte veldvolgorde. Alle optionele velden hebben zinvolle standaardwaarden zodat je alleen configureert wat je daadwerkelijk wilt wijzigen.


Inhoud vertalen

Enkel verzoek

import com.usepolylingo.polylingo.types.TranslateParams;
import com.usepolylingo.polylingo.types.TranslateResult;
 
TranslateResult result = client.translate(
    TranslateParams.builder()
        .content("Hello, world!")
        .targets(List.of("es", "fr", "de"))
        .build()
);
 
result.getTranslations().forEach((lang, text) ->
    System.out.println(lang + ": " + text)
);
// es: ¡Hola, mundo!
// fr: Bonjour le monde !
// de: Hallo Welt!

De TranslateParams builder accepteert content en targets als verplichte velden. Optionele parameters zijn onder andere format (plain, markdown, json, of html — automatisch gedetecteerd als weggelaten), source als taalhint, en model als standard (standaard) of advanced.

Formaatbehoud werkt hetzelfde als de rest van de PolyLingo API. Voor json inhoud worden alleen stringwaarden vertaald en sleutels, nesting en niet-string types blijven onaangeroerd. Voor markdown blijven koppen koppen en codeblokken worden letterlijk gelaten. Voor html worden tags en attributen behouden en alleen tekstknopen vertaald.

Een JSON locale-bestand vertalen

import com.fasterxml.jackson.databind.ObjectMapper;
import java.nio.file.Files;
import java.nio.file.Path;
 
ObjectMapper mapper = new ObjectMapper();
String sourceJson = Files.readString(Path.of("messages/en.json"));
 
TranslateResult result = client.translate(
    TranslateParams.builder()
        .content(sourceJson)
        .format("json")
        .targets(List.of("fr", "de", "ja"))
        .build()
);
 
result.getTranslations().forEach((locale, translated) -> {
    try {
        Object parsed = mapper.readValue(translated, Object.class);
        String pretty = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(parsed);
        Files.writeString(Path.of("messages/" + locale + ".json"), pretty);
        System.out.println("Wrote messages/" + locale + ".json");
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
});

Eén verzoek behandelt alle drie de locales. Sleutels zijn identiek aan de bron in elk uitvoerbestand.


Batchverzoeken

Verstuur tot 100 inhoudsitems in één verzoek, elk met een eigen id en optioneel format:

import com.usepolylingo.polylingo.types.BatchParams;
import com.usepolylingo.polylingo.types.BatchItem;
import com.usepolylingo.polylingo.types.BatchResult;
 
BatchResult result = client.batch(
    BatchParams.builder()
        .targets(List.of("es", "ja"))
        .addItem(BatchItem.builder().id("title").content("Welcome").build())
        .addItem(BatchItem.builder().id("body").content("Get started today.").build())
        .build()
);
 
for (BatchItemResult item : result.getResults()) {
    System.out.println(item.getId() + ": " + item.getTranslations());
}

Alle items delen dezelfde targets lijst. De id die je toewijst wordt behouden in de respons zodat je resultaten kunt terugkoppelen naar je brondata zonder afhankelijk te zijn van volgorde.


Async jobs

Voor lange documenten of grote vertaalwerkbelastingen accepteert de jobs API een verzoek, retourneert direct een job-ID, en laat je pollen voor het resultaat. De SDK behandelt dit op twee manieren.

Eén oproep die blijft pollen tot klaar

import com.usepolylingo.polylingo.types.JobsTranslateParams;
 
TranslateResult result = client.jobs().translate(
    JobsTranslateParams.builder()
        .content(longArticleText)
        .targets(List.of("fr", "de", "ja", "zh"))
        .pollInterval(Duration.ofSeconds(3))
        .timeout(Duration.ofMinutes(10))
        .onProgress(queuePosition ->
            System.out.println("Queue position: " + queuePosition))
        .build()
);
 
result.getTranslations().forEach((lang, text) ->
    System.out.println(lang + ": " + text.substring(0, 100) + "...")
);

De onProgress callback wordt bij elke poll aangeroepen met de huidige wachtrijpositie als een integer, of null als de API die niet teruggeeft. Gebruik het om voortgang te loggen of een UI bij te werken.

Handmatig in de wachtrij plaatsen en pollen

import com.usepolylingo.polylingo.types.CreateJobParams;
import com.usepolylingo.polylingo.types.Job;
 
Job job = client.jobs().create(
    CreateJobParams.builder()
        .content("Translate this.")
        .targets(List.of("es"))
        .build()
);
 
// Zelf pollen
Job status = client.jobs().get(job.getJobId());
System.out.println(status.getStatus()); // pending / processing / completed / failed

Utility endpoints

// Controleer API gezondheid (geen API-sleutel vereist)
HealthResponse health = client.health();
System.out.println(health.getStatus()); // "ok"
 
// Lijst ondersteunde talen (geen API-sleutel vereist)
LanguagesResponse langs = client.languages();
langs.getLanguages().forEach(l ->
    System.out.println(l.getCode() + " — " + l.getName())
);
 
// Controleer tokengebruik voor de huidige factureringsmaand
UsageResponse usage = client.usage();
System.out.println("Tokens used: " + usage.getUsage().getTokensUsed());
System.out.println("Tokens remaining: " + usage.getUsage().getTokensRemaining());

Foutafhandeling

Alle uitzonderingen zijn unchecked. Geen verplichte throws declaraties, geen gecontroleerde uitzonderingsketens om af te wikkelen:

import com.usepolylingo.polylingo.errors.*;
 
try {
    TranslateResult result = client.translate(
        TranslateParams.builder()
            .content("# Hello")
            .targets(List.of("es", "fr"))
            .format("markdown")
            .build()
    );
} catch (AuthException e) {
    // HTTP 401 — ongeldige, ontbrekende of ingetrokken API-sleutel
    System.out.println("Auth failed: " + e.getError());
} catch (RateLimitException e) {
    // HTTP 429 — per-minuut limiet bereikt
    e.getRetryAfter().ifPresent(s ->
        System.out.println("Retry after: " + s + "s")
    );
} catch (JobFailedException e) {
    // Async job bereikte een mislukte terminale status of polling time-out
    System.out.println("Job " + e.getJobId() + " failed: " + e.getError());
} catch (PolyLingoException e) {
    // Alle andere API-fouten
    System.out.println(e.getStatus() + ": " + e.getMessage());
}

RateLimitException.getRetryAfter() retourneert een Optional<Integer> — aanwezig met het aantal seconden om te wachten als de API die waarde bevat, anders leeg. JobFailedException.getJobId() geeft je de ID van de mislukte job voor logging of retry-logica.


Ontwerpnotities

Een paar beslissingen die het waard zijn om te weten als je de SDK evalueert:

Synchrone API. Elke methode blokkeert en retourneert direct een resultaat. Geen Future, geen CompletableFuture, geen reactieve streams. De jobs polling is het async verhaal van de SDK voor zware workloads — dien de job in, de SDK pollt op jouw thread en roept je onProgress callback aan als de wachtrijpositie wordt bijgewerkt.

Builder-patroon overal. Elk params-object gebruikt een builder. Geen positionele constructors betekent geen giswerk over argumentvolgorde, geen per ongeluk verwisselde velden, en duidelijke code op de aanroepplaats.

Één runtime-afhankelijkheid. Jackson voor JSON-serialisatie. Alles anders is standaardbibliotheek. Geen OkHttp, geen Apache HttpClient, geen Guava.

Java 11+. Gebruikt java.net.http.HttpClient geïntroduceerd in Java 11. Als je project Java 8 of eerder target, is de SDK niet compatibel.


Snelle referentie

MethodeEndpointAuth vereist
client.health()GET /healthNee
client.languages()GET /languagesNee
client.translate(...)POST /translateJa
client.batch(...)POST /translate/batchJa
client.usage()GET /usageJa
client.jobs().create(...)POST /jobsJa
client.jobs().get(jobId)GET /jobs/:idJa
client.jobs().translate(...)POST /jobs + pollingJa

Aan de slag

De SDK staat op Maven Central op central.sonatype.com/artifact/com.usepolylingo/polylingo. Broncode en Javadoc staan op github.com/UsePolyLingo/polylingo-Java. Volledige API-documentatie staat op usepolylingo.com/docs/sdk/java.

De gratis laag bevat 50.000 tokens per maand. Geen creditcard vereist.

<dependency>
  <groupId>com.usepolylingo</groupId>
  <artifactId>polylingo</artifactId>
  <version>0.1.0</version>
</dependency>

Haal je API-sleutel op