Zurück zum Blog
Maven coordinates for the PolyLingo Java SDK alongside a short Java client setup snippet.

Strukturierte Inhalte aus Java mit dem PolyLingo SDK übersetzen

By Robert

Übersetzen strukturierter Inhalte aus Java mit dem PolyLingo SDK

Das PolyLingo Java SDK ist jetzt auf Maven Central verfügbar. Es deckt die gesamte PolyLingo API ab: synchrone Übersetzung, Batch-Anfragen, asynchrone Jobs mit Polling und alle Dienstendpunkte. Es benötigt Java 11 oder höher, verwendet den HTTP-Client der Standardbibliothek und hat genau eine Laufzeitabhängigkeit: Jackson für JSON.


Installation

Maven

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

Gradle

implementation 'com.usepolylingo:polylingo:0.1.0'

Keine zusätzliche HTTP-Client-Abhängigkeit erforderlich. Das SDK verwendet java.net.http.HttpClient aus der Java 11 Standardbibliothek.


Einrichtung des Clients

import com.usepolylingo.polylingo.PolyLingo;

PolyLingo client = PolyLingo.builder()
    .apiKey(System.getenv("POLYLINGO_API_KEY"))
    .build();

Zwei optionale Builder-Parameter sind verfügbar:

PolyLingo client = PolyLingo.builder()
    .apiKey(System.getenv("POLYLINGO_API_KEY"))
    .baseUrl("https://api.usepolylingo.com/v1") // Standard, überschreiben für selbstgehostete Instanzen
    .timeout(Duration.ofSeconds(30))            // Standard ist 120 Sekunden
    .build();

Bewahren Sie Ihren API-Schlüssel in einer Umgebungsvariable auf. Niemals hartkodieren oder in die Versionskontrolle einchecken.

Das SDK verwendet durchgehend das Builder-Muster. Keine positionsabhängigen Konstruktoren, keine erforderliche Feldreihenfolge. Alle optionalen Felder haben sinnvolle Standardwerte, sodass Sie nur das konfigurieren, was Sie tatsächlich ändern müssen.


Übersetzen von Inhalten

Einzelne Anfrage

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!

Der TranslateParams-Builder akzeptiert content und targets als erforderliche Felder. Optionale Parameter sind format (plain, markdown, json oder html — wird automatisch erkannt, wenn ausgelassen), source als Sprachhinweis und model als entweder standard (Standard) oder advanced.

Die Formatbeibehaltung funktioniert wie im Rest der PolyLingo API. Bei json-Inhalten werden nur String-Werte übersetzt, Schlüssel, Verschachtelungen und Nicht-String-Typen bleiben unverändert. Bei markdown bleiben Überschriften Überschriften und Codeblöcke werden unverändert gelassen. Bei html werden Tags und Attribute erhalten und nur Textknoten übersetzt.

Übersetzen einer JSON-Lokalisierungsdatei

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);
    }
});

Eine Anfrage verarbeitet alle drei Lokale. Die Schlüssel sind in jeder Ausgabedatei identisch mit der Quelle.


Batch-Anfragen

Senden Sie bis zu 100 Inhalte in einer einzigen Anfrage, jeweils mit eigener id und optionalem 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 Elemente teilen sich dieselbe targets-Liste. Die von Ihnen vergebene id wird in der Antwort beibehalten, sodass Sie Ergebnisse ohne Reihenfolgeabhängigkeit auf Ihre Quelldaten abbilden können.


Asynchrone Jobs

Für lange Dokumente oder große Übersetzungsaufträge akzeptiert die Jobs-API eine Anfrage, gibt sofort eine Job-ID zurück und ermöglicht das Polling auf das Ergebnis. Das SDK unterstützt dies auf zwei Arten.

Ein Aufruf, der bis zum Abschluss pollt

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) + "...")
);

Der onProgress-Callback wird bei jedem Poll mit der aktuellen Position in der Warteschlange als Integer ausgelöst, oder null, wenn die API keine Position zurückgibt. Verwenden Sie ihn, um den Fortschritt zu protokollieren oder eine UI zu aktualisieren.

Manuelles Einreihen und Polling

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()
);

// Selbst pollen
Job status = client.jobs().get(job.getJobId());
System.out.println(status.getStatus()); // pending / processing / completed / failed

Dienstendpunkte

// API-Gesundheit prüfen (kein API-Schlüssel erforderlich)
HealthResponse health = client.health();
System.out.println(health.getStatus()); // "ok"

// Unterstützte Sprachen auflisten (kein API-Schlüssel erforderlich)
LanguagesResponse langs = client.languages();
langs.getLanguages().forEach(l ->
    System.out.println(l.getCode() + " — " + l.getName())
);

// Tokenverbrauch für den aktuellen Abrechnungsmonat prüfen
UsageResponse usage = client.usage();
System.out.println("Tokens verwendet: " + usage.getUsage().getTokensUsed());
System.out.println("Tokens verbleibend: " + usage.getUsage().getTokensRemaining());

Fehlerbehandlung

Alle Ausnahmen sind unchecked. Keine erzwungenen throws-Deklarationen, keine geprüften Ausnahmeketten zum Auflösen:

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 — ungültiger, fehlender oder widerrufener API-Schlüssel
    System.out.println("Authentifizierung fehlgeschlagen: " + e.getError());
} catch (RateLimitException e) {
    // HTTP 429 — Minutenlimit erreicht
    e.getRetryAfter().ifPresent(s ->
        System.out.println("Wartezeit: " + s + "s")
    );
} catch (JobFailedException e) {
    // Asynchroner Job erreichte einen Fehlerstatus oder Polling lief ab
    System.out.println("Job " + e.getJobId() + " fehlgeschlagen: " + e.getError());
} catch (PolyLingoException e) {
    // Alle anderen API-Fehler
    System.out.println(e.getStatus() + ": " + e.getMessage());
}

RateLimitException.getRetryAfter() gibt ein Optional<Integer> zurück — vorhanden mit der Anzahl Sekunden, falls die API diesen Wert liefert, sonst leer. JobFailedException.getJobId() liefert die ID des fehlgeschlagenen Jobs für Protokollierung oder Wiederholungslogik.


Designhinweise

Einige Entscheidungen, die Sie kennen sollten, wenn Sie das SDK bewerten:

Synchrone API. Jede Methode blockiert und gibt direkt ein Ergebnis zurück. Kein Future, kein CompletableFuture, keine reaktiven Streams. Das Polling der Jobs ist die asynchrone Lösung des SDK für große Lasten — Job absenden, SDK pollt im eigenen Thread und ruft Ihren onProgress-Callback bei Positionsänderungen in der Warteschlange auf.

Builder-Muster durchgehend. Jedes Parameterobjekt verwendet einen Builder. Keine positionsabhängigen Konstruktoren bedeutet kein Raten der Argumentreihenfolge, keine versehentlichen Feldvertauschungen und klarer Code an der Aufrufstelle.

Eine Laufzeitabhängigkeit. Jackson für JSON-Serialisierung. Alles andere ist Standardbibliothek. Kein OkHttp, kein Apache HttpClient, kein Guava.

Java 11+. Verwendet java.net.http.HttpClient, eingeführt in Java 11. Wenn Ihr Projekt Java 8 oder älter anvisiert, ist das SDK nicht kompatibel.


Schnelle Referenz

MethodeEndpunktAuth erforderlich
client.health()GET /healthNein
client.languages()GET /languagesNein
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

Erste Schritte

Das SDK ist auf Maven Central unter central.sonatype.com/artifact/com.usepolylingo/polylingo verfügbar. Quellcode und Javadoc sind unter github.com/UsePolyLingo/polylingo-Java. Die vollständige API-Dokumentation finden Sie unter usepolylingo.com/docs/sdk/java.

Der kostenlose Tarif umfasst 50.000 Tokens pro Monat. Keine Kreditkarte erforderlich.

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

Holen Sie sich Ihren API-Schlüssel