Translation Middleware for Express APIs and MongoDB

Ankit Gupta
Gramoday
Published in
2 min readFeb 6, 2022
Photo by Douglas Lopes on Unsplash

In this post, I am going to talk about how to automatically perform translation on API responses using swagger metadata config, in an express middleware.

The config-based approach has the below benefits:

  1. Removes duplicate code being added for each route/handler
  2. Takes a config-based approach to define the translation, which can make this nearly 100% error-free.
  3. Development speed — Adding translation to the APIs is a breeze

Database

For the database, a simple schema can be to create another translations collection that records the translations e.g.

// translations collection schema
{
table: string, // for e.g. crops
column_id: string, // this is the crop_id
column_id_value: int, // value for crop_id
column_to_translate: string, // this can be crop_name
en: string,
hi: string,
...
}

// query to lookup
db.translations.find({
table: 'crops',
column_id: 'crop_id',
column_id_value: 1,
column_to_translate: 'crop_name'
},
{
en: 1,
hi: 1,
_id: 0
})

One can add a compound index on the (table, column_id, column_id_value, column_to_translate) to optimize the read.

Since we always query by the 4 keys, we can also create a translationKey that merges these values and then index on this key instead.

For e.g., we could instead store <prefix>_crop_id_1_crop_name as the value for the translationKey and avoid passing in the value separately.

API Layer

In order to configure a translation middleware for your express APIs, you would need:

  1. Swagger based routes
  2. json-path library to traverse the JSON tree
  3. mung for transforming express response

Steps

  1. Define translationConfig.yaml

2. Include it in the main swaggger.yaml

3. Define the middleware translation.js

There are a few things going on in the above function:

  1. We go through all the translation configs defined in translationConfig.yaml
  2. Create the unique translation keys for each field using its corresponding translateFn
  3. Perform a one-time DB lookup for the keys in the collection named Translations
  4. Query the body for the fieldPaths we need to replace
  5. Find out the corresponding key nodes for these fieldPaths
  6. Substitute the value from the translation map (for the required lang) in the node value

Also, here is the simplified version of translationUtil.js

Thanks for reading!

--

--