dragoman 0.1.0

PID redirection and content negotiation server
dragoman-0.1.0 is not a library.

dragoman

A web server for scholarly PID (Persistent Identifier) resolution with full DOI content negotiation. Send a DOI as the URL path; receive a redirect to the landing page or metadata in any supported format depending on the Accept header.

Installation

Prerequisites

Install

git clone https://github.com/front-matter/dragoman
cd dragoman
cargo install --path .

This builds a release binary and installs it to ~/.cargo/bin/dragoman. Make sure ~/.cargo/bin is on your PATH (the Rust installer adds this automatically).

Local SQLite database

dragoman can serve metadata directly from a local SQLite database in the commonmeta format, bypassing the live Crossref/DataCite APIs. This dramatically reduces latency and API load for high-traffic deployments.

Database format

The database is a SQLite3 file with a single works table whose columns map one-to-one to the commonmeta v1.0 schema. The id column is the canonical DOI URL (e.g. https://doi.org/10.5281/zenodo.1234). Complex fields (contributors, references, …) are stored as JSON text.

You can build a database from any commonmeta-supported source using the commonmeta CLI.

Running the server

Start

# Default port 3000
dragoman start

# Custom port
dragoman start --port 8080

# With a local database
dragoman start --db /data/commonmeta-2026-06-15.sqlite3

# Write a PID file so the process can be stopped later
dragoman start --pid-file /tmp/dragoman.pid

# All options together
dragoman start --port 8080 --db /data/commonmeta-2026-06-15.sqlite3 --pid-file /tmp/dragoman.pid

Options can also be supplied as environment variables (flags take precedence):

PORT=8080 DRAGOMAN_DB=/data/commonmeta-2026-06-15.sqlite3 RUST_LOG=dragoman=debug dragoman start

During development you can use cargo run in place of the installed binary:

# Run from the project root — the sqlite3 file in the root is loaded by filename
cargo run -- start --db commonmeta-2026-06-15.sqlite3

# Or with a full path
cargo run -- start --db /data/commonmeta-2026-06-15.sqlite3

Error: port already in use

If the chosen port is already in use, the server logs an error and exits:

ERROR dragoman: failed to bind  port=3000  error=Address already in use (os error 48)

Choose a different port with --port or stop the process that holds the port.

Error: database file not found

If --db points to a path that does not exist, the server exits at startup before accepting any traffic:

ERROR dragoman: failed to open database  path=…  error=sqlite file not found: '…'

Pass the correct path or an absolute path to avoid working-directory ambiguity.

Stop

# Stop using the default PID file location (/tmp/dragoman.pid)
dragoman stop

# Stop using a custom PID file
dragoman stop --pid-file /var/run/dragoman.pid

dragoman stop sends SIGTERM to the running process. The server handles the signal gracefully: it finishes in-flight requests and removes the PID file before exiting. Pressing Ctrl-C has the same effect.

CLI reference

dragoman <COMMAND>

Commands:
  start  Start the server (runs in the foreground)
  stop   Stop a running server by sending SIGTERM to its PID file
  help   Print help

dragoman start [OPTIONS]
  -p, --port <PORT>          TCP port to listen on [env: PORT] [default: 3000]
  -d, --db <PATH>            Local commonmeta SQLite3 database [env: DRAGOMAN_DB]
      --pid-file <PATH>      Write PID to this file on startup [env: DRAGOMAN_PID_FILE]

dragoman stop [OPTIONS]
      --pid-file <PATH>      PID file to read [env: DRAGOMAN_PID_FILE] [default: /tmp/dragoman.pid]

Environment variables

Variable Default Description
PORT 3000 TCP port to listen on.
DRAGOMAN_DB (none) Path to a local commonmeta SQLite3 database. Metadata is served from the database before falling back to the live API. The server exits on startup if the path is set but the file cannot be opened.
DRAGOMAN_PID_FILE (none) Path for the PID file written by start and read by stop.
RUST_LOG dragoman=info Log filter (see tracing-subscriber). Use dragoman=debug to log per-request cache hits.

Usage

Redirect (HTML / browser)

When the Accept header prefers text/html or is absent, dragoman redirects to the DOI's landing page:

# Follow the redirect
curl -L http://localhost:3000/10.5281/zenodo.1089100

# Inspect the redirect target without following
curl -s -o /dev/null -w "%{redirect_url}" http://localhost:3000/10.5281/zenodo.1089100
# https://zenodo.org/record/1089100

Content negotiation

Send an Accept header to receive metadata instead of a redirect.

BibTeX

curl -H "Accept: application/x-bibtex" \
     http://localhost:3000/10.5281/zenodo.1089100

CSL-JSON

curl -H "Accept: application/vnd.citationstyles.csl+json" \
     http://localhost:3000/10.5281/zenodo.1089100

DataCite JSON

curl -H "Accept: application/vnd.datacite.datacite+json" \
     http://localhost:3000/10.5281/zenodo.1089100

RIS

curl -H "Accept: application/x-research-info-systems" \
     http://localhost:3000/10.5281/zenodo.1089100

Crossref XML

curl -H "Accept: application/vnd.crossref.unixref+xml" \
     http://localhost:3000/10.1016/j.jaci.2019.09.015

Schema.org JSON-LD

curl -H "Accept: application/vnd.schemaorg.ld+json" \
     http://localhost:3000/10.5281/zenodo.1089100

Formatted citation

text/x-bibliography accepts optional style= and locale= parameters. Style names come from the CSL style repository; locale codes from the CSL locales repository.

# APA (default)
curl -H "Accept: text/x-bibliography; style=apa" \
     http://localhost:3000/10.5281/zenodo.1089100

# Vancouver in French
curl -H "Accept: text/x-bibliography; style=vancouver; locale=fr-FR" \
     http://localhost:3000/10.5281/zenodo.1089100

Query parameter overrides

Use ?format= instead of an Accept header:

curl "http://localhost:3000/10.5281/zenodo.1089100?format=bibtex"
curl "http://localhost:3000/10.5281/zenodo.1089100?format=citation&style=apa&locale=de-DE"

Force a specific registration agency (useful for testing):

curl -H "Accept: application/x-bibtex" \
     "http://localhost:3000/10.5281/zenodo.1089100?source=datacite"

Supported formats

Accept header ?format= value Notes
application/vnd.citationstyles.csl+json csl
application/vnd.commonmeta+json commonmeta
application/vnd.datacite.datacite+json datacite
application/vnd.datacite.datacite+xml datacite_xml
application/vnd.crossref.unixref+xml crossref_xml
application/vnd.crossref.unixsd+xml crossref_xml alias
application/x-bibtex bibtex
application/x-research-info-systems ris
application/vnd.schemaorg.ld+json schemaorg
text/x-bibliography citation style= and locale= params
text/html / (absent) 307 redirect to landing page

HTTP status codes

Code Meaning
200 Metadata returned
307 Redirect to landing page
404 DOI not found
406 Requested content type not supported
502 Upstream API error

License

MIT