The Dragomon RESTful API


  1. Create a simple distributed replacement for gettext.
  2. Allow easy updates to translations.
  3. Lazy evaluation and updates to the message catalog.
  4. Compiled updates to the message catalog (like gettext currently does).


Dragomon currently is using MongoDB for its backend, but the overarching design is not meant to be depedant on the specific backend.

Also, the API is meant to be used entirely through a browser so it is possible to support both client and server applications.

The basic idea is to allow attempts to get some phrase will serve double duty by adding new phrases to the catalog that need to be translated. This makes it possible for application content as well as content created within the application to utilize the catalog. For example, in a CMS application you might want to translate the text of buttons in the interface as well as actual articles people write.


All responses return either a JSON description of the resource or plain text in the case of a value. All strings should be encoded via utf-8.

All actionable resources will accept a JSON document describing the content. Any extra content not required by this API will be kept for use by clients.

The Service Document and URL Templates

The root URL ('/api') returns a JSON service doc with the following URL endpoints.

result = self.json({
    'base': cherrypy.request.base,
    'self': cherrypy.request.base + '/api',
    'catalog' : '/api/catalog/{catalog}',
    'language': '/api/catalog/{catalog}/{language}',
    'phrases' : '/api/{catalog}/{language}',
    'phrase': '/api/{catalog}/{language}/{phrase}',

The endpoints are described using URL templates. The client implementation already has the ability to parse the URL for the required fields.

The catalog field refers to a dragoman catalog and not a language catalog like in gettext. These are the namespaces you provide for a specific project or application.

The langauge is the abbreviation for the desired language. Usually these are two letters for the gettext provided languages, but since you can add languages (en_UK for example), it can be any string.

The following descriptions assume the '/api' or service document URL as a base URL.

The purpose for this is to reduce chatter by constantly traversing using hyperlinks, while still allowing discovery.

Languages (language)

This provides a means to add and remove languages to the list of available languages in each catalog.

POST /language
Adds a language for catalogs to use ::
{ "abbrev" : "en_UK",
"name" : "English (UK)" }
DELETE /language/{abbrev}
Removes that language option

Catalogs (catalog)

Catalogs are namespaces for language catalogs or "phrases".

GET /catalog
Returns a list of catalogs
GET /catalog/{catalog}
Returns infomation on a catalog such as what languages are available.
POST /catalog/{catalog}/{language}

Creates a catalog.

If the language is provided and no document body is provided then a placeholder will be created. This is partially due to MongoDBs Python client and the fact that a MongoDB can't have an empty collection.

If a language is provided in the URL, a body must also be present. The request body should be a JSON document that contains a dictionary for each langauge you want initialize the catalog with. For example

{ "es": [
  { "phrase" : "I like it",
    "translation" : "Me gustalo" },

  { "phrase" : "I don't like it",
    "translation" : "No me gusta" }

In the future it would also be beneficial to allow posting a .po file, but that is not currently supported via the API.


GET /{catalog}/{phrase}
The phrase should be a percent encoded string. This will return the utf-8 encoded translated phrase.
POST /{catalog}/{phrase}

Updates the phrase value

{ "phrase" : "I like it"
  "translation": "Me gusta lo" }

If the translation already exists it will overwrite the value. This can be set to return a 409 (conflict) in the case of an existing translation by adding

{ "phrase" : "I like it"
  "translation": "Me gusta lo",
  "safe" : true }


The responses returned from any actionable resource return a JSON object with the following structure

{ "status" : "HTTP Status",
  "message": "status message"
  "url": "/new/url/created" }

The status includes the HTTP status code along with a message describing the result. In the case of a conflict, the message may provide instructions on how to fix the conflict, otherwise, it will simply clarify what action was performed.

The value of the response provides information on any created resources. This is primarily going to be a 'url' that points to the resource.