Skip to content

Running the search API

Linked Open Limburg (LOL) publishes a ready-to-run search data layer: a GraphQL API over the curated Limburg collections. If you are building a presentation layer on top, just run our prebuilt Docker images to bring up the search API:

  • codeberg.org/limburg/lol/search-api (the read side): the GraphQL API on :4000;
  • codeberg.org/limburg/lol/search-indexer (the write side): retrieves datasets via the Dataset Register and indexes them into Typesense.

The LOL components and Docker images are built on LD Elements (LDE).

Run it

Grab the one Compose file and run:

sh
curl -O https://codeberg.org/limburg/lol/raw/branch/main/infra/search-indexer/docker-compose.yml
docker compose up -d               # Typesense + the API on :4000
docker compose run --rm indexer    # fill Typesense (index Drapo)

Our images default to the :latest tag, and the Compose file gives them pull_policy: always, so every up (and every run --rm indexer) checks the registry and you stay on the current build without thinking about it. A stack that is already running does not upgrade itself, though: re-run docker compose up -d to move it forward – Compose pulls, recreates the containers whose image changed and leaves the rest alone. Set LOL_TAG to a release if you would rather pin, or pass --pull never to work offline. To upgrade Typesense, which the Compose file pins to an exact version, take a newer Compose file.

One exception to upgrading without thinking about it: a release that changes the search schema needs the index rebuilt from empty. Typesense collections are created on demand and never migrated, so an existing index keeps field definitions that predate the new schema, and a filter or facet on a field it does not know fails. When the release notes say so, take both volumes and re-index:

sh
docker compose --profile indexer down -v   # drops the Typesense data AND the provenance file
docker compose up -d                       # back to Typesense + the API
docker compose run --rm indexer            # rebuild the collections from scratch

--profile indexer is not optional here. The indexer is a profiled service, so a plain docker compose down -v never considers it and leaves its provenance volume behind – and a dropped Typesense volume alone means the indexer reads every dataset as unchanged, skips them all, and the fresh collections stay empty.

Everything is pre-configured (the register, dataset selection, data dir and Typesense key) so there is nothing to set; on Linux, set DOCKER_GID for the QLever import (it defaults to 0, which is correct on Docker Desktop).

The API serves GraphQL at http://localhost:4000/graphql.

Using the search API covers what it serves – the collections, their filters and facets – with example queries to start from.

Customization

There is a gradient of customization, and in most cases you don’t need to clone this repository:

Configuration only

Point the indexer elsewhere, or index more, with plain environment variables on the same image. For example, change the dataset selection:

sh
DATASETS="https://id.drapo.nl/dataset/drapo-schemaorg https://example.org/dataset/other" \
  docker compose run --rm indexer

REGISTRY_ENDPOINT, TYPESENSE_*, DATA_DIR and the rest are environment too; see the LDE docs for the complete list.

Change the search schema

The search schema (@lol/search-schema) defines which objects, fields and facets the API exposes. To change the search schema, clone this repository and use the dev overlay (docker-compose.dev.yml): it runs the stock LDE images with your locally built schema mounted:

sh
git clone https://codeberg.org/limburg/lol
cd lol
npm install
# edit packages/search-schema/src/…, then:
npx nx up        # Typesense + API on the stock LDE images, schema mounted
npx nx index     # (re)index Drapo – bundles the schema first
npx nx down

nx up / index / down wrap docker compose -f docker-compose.yml -f docker-compose.dev.yml … and bundle first; run that raw command if you prefer. The deployment README has the details.