Grout serves map tiles (mbtiles) data which can be consumed in web front ends by Leaflet etc. Useful region metadata is also provided
- Metadata about available datasets:
/metadata - Tile data:
/tile/:dataset/:level/:z/:x/:y" - Admin 0 (country) metadata for all countries in a dataset:
/region-metadata/:dataset/admin0 - Region metadata for a single country:
/region-metadata/:dataset/:level/:iso
Countries are identified by three letter ISO codes.
:level values are prefixed with "admin".
NB There is only a single global endpoint for admin0 region metadata, which provides level 0 metadata for all country
ISOs. For all other levels, there are only country-specific endpoints, identified with the ISO.
Grout is implemented as an express server in Typescript.
Developed with node v22.
For testing, a partial gadm41 dataset is included with tile data and region metadata at levels 0 and 1.
Run in dev mode with hot reloading managed by vite: npm run dev
Build for production: npm run build
Run in production mode: npm run prod
In both modes, local run is on port 5000. Port is configured in config/grout.config.json (for running in production)
and vite.config.mts (for running in dev mode).
The server needs to be running for the integration tests to pass.
Run unit and integration tests with npm run test
Run tests with coverage using npm run coverage
Manual testing can be done by viewing test.html in the browser. Here you can choose to view any available dataset on
either a local grout server, or deployed to mrcdata. The page is available at the /test route of any running server.
Run lint with npm run lint. To do any possible automatic fixes run npm run lint-fix.
See the docker folder for Dockerfile and scripts to build, push, run, stop, and push branch tag for the image. The run
script always pulls. The image is pushed to the ghcr.io registry.
We use JSON Schema to define the format of JSON responses, and to validate that expected data formats are returned
during integration tests. JSON schema files can be found in the ./schema folder. The Ajv package is used for validation.
Response.schema.json defines the generic schema for all responses (with status, data and errors properties),
while the other schema files define the expected format of the data property for individual endpoints. When defining a new
endpoint, or modifying the format of an existing one, you should add or edit the corresponding
schema file, for the data part of the response.
The Response schema includes a $ref for the data property, with value grout-data. In order for this $ref to be
satisfied during validation, the expected data schema needs to be given $id: "grout-data". This happens in the integration
test helper method validateResponse (called from getData), which takes a data schema name parameter. It loads both the Response
and expected data schema, and appends $id: "grout-data to the data schema before performing validation. This works so
long as there is only one loaded schema with that $id.
A better solution for dynamic nested schema would be to use $dynamicRef. However, a longstanding bug
with $dynamicRef in Ajv prevents this.