#api-bindings #bindings #rest-client #localization #rest #api

traduora

REST API bindings for Traduora, an open-source translation management platform

4 releases (breaking)

0.4.0 Apr 3, 2022
0.3.0 Mar 20, 2022
0.2.0 Nov 7, 2021
0.1.0 Oct 27, 2021

#119 in Internationalization (i18n)

23 downloads per month

MIT/Apache

125KB
2K SLoC

Traduora API bindings

Crates.io docs.rs Crates.io CI

This crate implements API bindings to communicate with a Traduora instance. You can find the list of implemented endpoints below. Traduora's general API documentation is available in their documentation and an (up-to-date) endpoint documentation can be found here.

The API was originally implemented for version v0.19.1 and was also tested with this version. When you're reading this, it's probably not actively maintained anymore, but it should still be passively maintained. Feel free to open an issue or a PR and it will probably get answered in a few days.

All endpoints are contained in the api module. To use them, you can simply instantiate one, create a Traduora client and call endpoint.query(&client) or the async equivalent with an AsyncTraduora client and endpoint.query_async(&async_client). On success, the endpoint then returns a struct that is specific to the endpoint, providing the data that was parsed from Traduora's response. For more fine-grained control, you can choose your own type to deserialize the response into by calling endpoint.query_custom(&client) instead. The type just has to implement serde::DeserializeOwned and you're good to go.

Some endpoints require authentication before Traduora allows you to access them. This is modelled at type level for this crate. Calling an endpoint requiring authentication without authentication leads to a compile-time error instead of erroring only at run time. If you have an Traduora<Unauthenticated> instance, this means you are not logged in, while a Traduora<Authenticated> instance symbolizes an authenticated client. This check is not perfect however, so you might still get error related to invalid authentication. This can happen if your client is alive for a long time so that its access token expires or if you construct your client by passing the access token yourself (see TraduoraBuilder::with_access_token).

Usage examples

Creating a new term:

use traduora::{
    api::{terms::CreateTerm, ProjectId},
    Login, Query, Traduora,
};

let client = Traduora::with_auth(
    "localhost:8080",
    Login::password("user@mail.example", "password"),
).unwrap();
let term = CreateTerm::new(
    "hello.world",
    ProjectId::new("b1001dd9-e1c0-4fb0-a60d-eaaec304d332"),
);

let new_term = term.query(&client).unwrap();

assert!(new_term.labels.is_empty());
assert_eq!("hello.world", new_term.value);

Design

The design of this crate is heavily inspired (=outright stolen) from the GitLab API crate. For details, you can read the excellent blog post Designing Rust bindings for REST APIs by Ben Boeckel. This crate calls the Query and AsyncQuery traits of the GitLab crate CustomQuery and AsyncCustomQuery instead as the normal Query and AsyncQuery traits return a DefaultModel type to make the crate easier to use.

Implementation progress

The endpoints from this list are taken from here

Status values:      ✅ Done    |    ☑ Done but missing documentation because API docs are unclear    |    ❌ Not yet implemented

Status Method Endpoint Type
POST /api/v1/auth/change-password api::auth::ChangePassword
POST /api/v1/auth/forgot-password
GET /api/v1/auth/providers api::auth::Providers
POST /api/v1/auth/reset-password
POST /api/v1/auth/signup-provider
POST /api/v1/auth/signup api::auth::Signup
POST /api/v1/auth/token api::auth::Token
GET /api/v1/locales api::locales::AllLocales
POST /api/v1/projects/{projectId}/clients/{clientId}/rotate-secret
DELETE /api/v1/projects/{projectId}/clients/{clientId}
PATCH /api/v1/projects/{projectId}/clients/{clientId}
GET /api/v1/projects/{projectId}/clients
POST /api/v1/projects/{projectId}/clients
GET /api/v1/projects/{projectId}/exports
POST /api/v1/projects/{projectId}/imports
DELETE /api/v1/projects/{projectId}/invites/{inviteId}
PATCH /api/v1/projects/{projectId}/invites/{inviteId}
GET /api/v1/projects/{projectId}/invites
POST /api/v1/projects/{projectId}/invites
DELETE /api/v1/projects/{projectId}/labels/{labelId}/terms/{termId}/translations/{localeCode}
POST /api/v1/projects/{projectId}/labels/{labelId}/terms/{termId}/translations/{localeCode}
DELETE /api/v1/projects/{projectId}/labels/{labelId}/terms/{termId}
POST /api/v1/projects/{projectId}/labels/{labelId}/terms/{termId}
DELETE /api/v1/projects/{projectId}/labels/{labelId}
PATCH /api/v1/projects/{projectId}/labels/{labelId}
GET /api/v1/projects/{projectId}/labels
POST /api/v1/projects/{projectId}/labels
GET /api/v1/projects/{projectId}/plan
GET /api/v1/projects/{projectId}/stats
DELETE /api/v1/projects/{projectId}/terms/{termId} api::terms::DeleteTerm
PATCH /api/v1/projects/{projectId}/terms/{termId} api::terms::EditTerm
GET /api/v1/projects/{projectId}/terms api::terms::Terms
POST /api/v1/projects/{projectId}/terms api::terms::CreateTerm
DELETE /api/v1/projects/{projectId}/translations/{localeCode} api::translations::DeleteLocale
GET /api/v1/projects/{projectId}/translations/{localeCode} api::translations::Translations
PATCH /api/v1/projects/{projectId}/translations/{localeCode} api::translations::EditTranslation
GET /api/v1/projects/{projectId}/translations api::translations::Locales
POST /api/v1/projects/{projectId}/translations api::translations::CreateLocale
DELETE /api/v1/projects/{projectId}/users/{userId}
PATCH /api/v1/projects/{projectId}/users/{userId}
GET /api/v1/projects/{projectId}/users
DELETE /api/v1/projects/{projectId} api::projects::DeleteProject
GET /api/v1/projects/{projectId} api::projects::ShowProject
PATCH /api/v1/projects/{projectId} api::projects::EditProject
GET /api/v1/projects api::projects::Projects
POST /api/v1/projects api::projects::CreateProject
DELETE /api/v1/users/me api::users::DeleteMe
GET /api/v1/users/me api::users::Me
PATCH /api/v1/users/me api::users::EditMe

License

Licensed under either of

Your choice.

Dependencies

~5–17MB
~238K SLoC