generate API docs 📝
This commit is contained in:
parent
a794851e76
commit
ab9f1af672
6 changed files with 1018 additions and 169 deletions
|
@ -13,4 +13,6 @@ EXPOSE 3000
|
||||||
ENV HOSTNAME v5.db.transport.rest
|
ENV HOSTNAME v5.db.transport.rest
|
||||||
ENV PORT 3000
|
ENV PORT 3000
|
||||||
|
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
CMD ["node", "index.js"]
|
CMD ["node", "index.js"]
|
||||||
|
|
455
api-docs.js
Normal file
455
api-docs.js
Normal file
|
@ -0,0 +1,455 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const generateApiDocs = require('hafas-rest-api/tools/generate-docs')
|
||||||
|
const {api} = require('./api')
|
||||||
|
|
||||||
|
const HEAD = `\
|
||||||
|
# \`v5.db.transport.rest\` API documentation
|
||||||
|
|
||||||
|
[\`v5.db.transport.rest\`](https://v5.db.transport.rest/) is a [REST API](https://restfulapi.net). Data is being returned as [JSON](https://www.json.org/).
|
||||||
|
|
||||||
|
You can just use the API without authentication. There's a [rate limit](https://apisyouwonthate.com/blog/what-is-api-rate-limiting-all-about) of 100 request/minute (burst 200 requests/minute) set up.
|
||||||
|
|
||||||
|
*Note:* For [URL-encoding](https://de.wikipedia.org/wiki/URL-Encoding), this documentation uses the \`url-encode\` tool of the [\`url-decode-encode-cli\` package](https://www.npmjs.com/package/url-decode-encode-cli).
|
||||||
|
`
|
||||||
|
|
||||||
|
const order = [
|
||||||
|
'/locations',
|
||||||
|
'/stops/nearby',
|
||||||
|
'/stops/reachable-from',
|
||||||
|
'/stops/:id',
|
||||||
|
'/stops/:id/departures',
|
||||||
|
'/stops/:id/arrivals',
|
||||||
|
'/journeys',
|
||||||
|
'/journeys/:ref',
|
||||||
|
'/trips/:id',
|
||||||
|
'/stations',
|
||||||
|
'/stations/:id',
|
||||||
|
'/radar',
|
||||||
|
]
|
||||||
|
|
||||||
|
const descriptions = {
|
||||||
|
'/locations': `\
|
||||||
|
Uses [\`hafasClient.locations()\`](https://github.com/public-transport/hafas-client/blob/5/docs/locations.md) to **find stops/stations, POIs and addresses matching \`query\`**.
|
||||||
|
`,
|
||||||
|
'/stops/nearby': `\
|
||||||
|
Uses [\`hafasClient.nearby()\`](https://github.com/public-transport/hafas-client/blob/5/docs/nearby.md) to **find stops/stations close to the given geolocation**.
|
||||||
|
`,
|
||||||
|
'/stops/reachable-from': `\
|
||||||
|
Uses [\`hafasClient.reachableFrom()\`](https://github.com/public-transport/hafas-client/blob/5/docs/reachable-from.md) to **find stops/stations reachable within a certain time from an address**.
|
||||||
|
`,
|
||||||
|
'/stops/:id': `\
|
||||||
|
Uses [\`hafasClient.stop()\`](https://github.com/public-transport/hafas-client/blob/5/docs/stop.md) to **find a stop/station by ID**.
|
||||||
|
`,
|
||||||
|
'/stops/:id/departures': `\
|
||||||
|
Uses [\`hafasClient.departures()\`](https://github.com/public-transport/hafas-client/blob/5/docs/departures.md) to **get departures at a stop/station**.
|
||||||
|
`,
|
||||||
|
'/stops/:id/arrivals': `\
|
||||||
|
Works like [\`/stops/:id/departures\`](#get-stopsiddepartures), except that it uses [\`hafasClient.arrivals()\`](https://github.com/public-transport/hafas-client/blob/5/docs/arrivals.md) to **arrivals at a stop/station**.
|
||||||
|
`,
|
||||||
|
'/stations': `\
|
||||||
|
If the \`query\` parameter is used, it will use [\`db-stations-autocomplete\`](https://npmjs.com/package/db-stations-autocomplete) to autocomplete *Deutsche Bahn*-operated stops/stations. Otherwise, it will filter the stops/stations in [\`db-stations\`](https://npmjs.com/package/db-stations).
|
||||||
|
|
||||||
|
Instead of receiving a JSON response, you can request [newline-delimited JSON](http://ndjson.org) by sending \`Accept: application/x-ndjson\`.
|
||||||
|
`,
|
||||||
|
'/stations/:id': `\
|
||||||
|
Returns a stop/station from [\`db-stations\`](https://npmjs.com/package/db-stations).
|
||||||
|
`,
|
||||||
|
'/journeys': `\
|
||||||
|
Uses [\`hafasClient.journeys()\`](https://github.com/public-transport/hafas-client/blob/5/docs/journeys.md) to **find journeys from A (\`from\`) to B (\`to\`)**.
|
||||||
|
|
||||||
|
\`from\` (A), \`to\` (B), and the optional \`via\` must each have one of these formats:
|
||||||
|
|
||||||
|
- as stop/station ID (e.g. \`from=8010159\` for *Halle (Saale) Hbf*)
|
||||||
|
- as a POI (e.g. \`from.id=991561765&from.latitude=51.48364&from.longitude=11.98084\` for *Halle+(Saale),+Stadtpark+Halle+(Grünanlagen)*)
|
||||||
|
- as an address (e.g. \`from.latitude=51.25639&from.longitude=7.46685&from.address=Hansestadt+Breckerfeld,+Hansering+3\` for *Hansestadt Breckerfeld, Hansering 3*)
|
||||||
|
|
||||||
|
### Pagination
|
||||||
|
|
||||||
|
Given a response, you can also fetch more journeys matching the same criteria. Instead of \`from*\`, \`to*\` & \`departure\`/\`arrival\`, pass \`earlierRef\` from the first response as \`earlierThan\` to get journeys "before", or \`laterRef\` as \`laterThan\` to get journeys "after".
|
||||||
|
|
||||||
|
Check the [\`hafasClient.journeys()\` docs](https://github.com/public-transport/hafas-client/blob/5/docs/journeys.md) for more details.
|
||||||
|
`,
|
||||||
|
'/journeys/:ref': `\
|
||||||
|
Uses [\`hafasClient.refreshJourney()\`](https://github.com/public-transport/hafas-client/blob/5/docs/refresh-journey.md) to **"refresh" a journey, using its \`refreshToken\`**.
|
||||||
|
|
||||||
|
The journey will be the same (equal \`from\`, \`to\`, \`via\`, date/time & vehicles used), but you can get up-to-date realtime data, like delays & cancellations.
|
||||||
|
`,
|
||||||
|
'/trips/:id': `\
|
||||||
|
Uses [\`hafasClient.trip()\`](https://github.com/public-transport/hafas-client/blob/5/docs/trip.md) to **fetch a trip by ID**.
|
||||||
|
|
||||||
|
A trip is a specific vehicle, stopping at a series of stops at specific points in time. Departures, arrivals & journey legs reference trips by their ID.
|
||||||
|
`,
|
||||||
|
'/radar': `\
|
||||||
|
Uses [\`hafasClient.radar()\`](https://github.com/public-transport/hafas-client/blob/5/docs/radar.md) to **find all vehicles currently in an area**, as well as their movements.
|
||||||
|
`,
|
||||||
|
}
|
||||||
|
|
||||||
|
const examples = {
|
||||||
|
'/locations': `\
|
||||||
|
### Example
|
||||||
|
|
||||||
|
\`\`\`shell
|
||||||
|
curl 'https://v5.db.transport.rest/locations?query=halle&results=1' -s | jq
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
\`\`\`js
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "stop",
|
||||||
|
"id": "8010159",
|
||||||
|
"name": "Halle (Saale) Hbf",
|
||||||
|
"location": {
|
||||||
|
"type": "location",
|
||||||
|
"id": "8010159",
|
||||||
|
"latitude": 51.477079,
|
||||||
|
"longitude": 11.98699
|
||||||
|
},
|
||||||
|
"products": {
|
||||||
|
"nationalExpress": true,
|
||||||
|
"national": true,
|
||||||
|
// …
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
\`\`\`
|
||||||
|
`,
|
||||||
|
'/stops/nearby': `\
|
||||||
|
### Example
|
||||||
|
|
||||||
|
\`\`\`shell
|
||||||
|
curl 'https://v5.db.transport.rest/stops/nearby?latitude=53.5711&longitude=10.0015' -s | jq
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
\`\`\`js
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "stop",
|
||||||
|
"id": "694800",
|
||||||
|
"name": "Böttgerstraße, Hamburg",
|
||||||
|
"location": {
|
||||||
|
"type": "location",
|
||||||
|
"id": "694800",
|
||||||
|
"latitude": 53.568356,
|
||||||
|
"longitude": 9.995528
|
||||||
|
},
|
||||||
|
"products": { /* … */ },
|
||||||
|
"distance": 498,
|
||||||
|
},
|
||||||
|
// …
|
||||||
|
{
|
||||||
|
"type": "stop",
|
||||||
|
"id": "694802",
|
||||||
|
"name": "Bahnhof Dammtor, Hamburg",
|
||||||
|
"location": {
|
||||||
|
"type": "location",
|
||||||
|
"id": "694802",
|
||||||
|
"latitude": 53.561048,
|
||||||
|
"longitude": 9.990315
|
||||||
|
},
|
||||||
|
"products": { /* … */ },
|
||||||
|
"distance": 1340,
|
||||||
|
},
|
||||||
|
// …
|
||||||
|
]
|
||||||
|
\`\`\`
|
||||||
|
`,
|
||||||
|
'/stops/reachable-from': `\
|
||||||
|
### Example
|
||||||
|
|
||||||
|
\`\`\`shell
|
||||||
|
curl 'https://v5.db.transport.rest/stops/reachable-from?latitude=53.553766&longitude=9.977514&address=Hamburg,+Holstenwall+9' -s | jq
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
\`\`\`js
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"duration": 1,
|
||||||
|
"stations": [
|
||||||
|
{
|
||||||
|
"type": "stop",
|
||||||
|
"id": "694815",
|
||||||
|
"name": "Handwerkskammer, Hamburg",
|
||||||
|
"location": { /* … */ },
|
||||||
|
"products": { /* … */ },
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
// …
|
||||||
|
{
|
||||||
|
"duration": 5,
|
||||||
|
"stations": [
|
||||||
|
{
|
||||||
|
"type": "stop",
|
||||||
|
"id": "694807",
|
||||||
|
"name": "Feldstraße (U), Hamburg",
|
||||||
|
"location": { /* … */ },
|
||||||
|
"products": { /* … */ },
|
||||||
|
// …
|
||||||
|
},
|
||||||
|
// …
|
||||||
|
]
|
||||||
|
},
|
||||||
|
// …
|
||||||
|
]
|
||||||
|
\`\`\`
|
||||||
|
`,
|
||||||
|
'/stops/:id': `\
|
||||||
|
### Example
|
||||||
|
|
||||||
|
\`\`\`shell
|
||||||
|
curl 'https://v5.db.transport.rest/stops/8010159' -s | jq
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
\`\`\`js
|
||||||
|
{
|
||||||
|
"type": "stop",
|
||||||
|
"id": "8010159",
|
||||||
|
"ids": {
|
||||||
|
"dhid": "de:15002:8010159",
|
||||||
|
"MDV": "8010159",
|
||||||
|
"NASA": "8010159"
|
||||||
|
},
|
||||||
|
"name": "Halle (Saale) Hbf",
|
||||||
|
"location": {
|
||||||
|
"type": "location",
|
||||||
|
"id": "8010159",
|
||||||
|
"latitude": 51.477079,
|
||||||
|
"longitude": 11.98699
|
||||||
|
},
|
||||||
|
"products": { /* … */ },
|
||||||
|
// …
|
||||||
|
}
|
||||||
|
\`\`\`
|
||||||
|
`,
|
||||||
|
'/stations': `\
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
\`\`\`shell
|
||||||
|
# autocomplete using db-stations-autocomplete
|
||||||
|
curl 'https://v5.db.transport.rest/stations?query=dammt' -s | jq
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
\`\`\`js
|
||||||
|
{
|
||||||
|
"8002548": {
|
||||||
|
"id": "8002548",
|
||||||
|
"relevance": 0.8572361756428573,
|
||||||
|
"score": 9.175313823998414,
|
||||||
|
"weight": 1212,
|
||||||
|
"type": "station",
|
||||||
|
"ril100": "ADF",
|
||||||
|
"name": "Hamburg Dammtor",
|
||||||
|
"location": {
|
||||||
|
"type": "location",
|
||||||
|
"latitude": 53.560751,
|
||||||
|
"longitude": 9.989566
|
||||||
|
},
|
||||||
|
"operator": {
|
||||||
|
"type": "operator",
|
||||||
|
"id": "hamburger-verkehrsverbund-gmbh",
|
||||||
|
"name": "BWVI"
|
||||||
|
},
|
||||||
|
"address": {
|
||||||
|
"city": "Hamburg",
|
||||||
|
"zipcode": "20354",
|
||||||
|
"street": "Dag-Hammarskjöld-Platz 15"
|
||||||
|
},
|
||||||
|
// …
|
||||||
|
},
|
||||||
|
// …
|
||||||
|
}
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
\`\`\`shell
|
||||||
|
# filter db-stations by \`hasParking\` property
|
||||||
|
curl 'https://v5.db.transport.rest/stations?hasParking=true' -s | jq
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
\`\`\`js
|
||||||
|
{
|
||||||
|
"8000001": {
|
||||||
|
"type": "station",
|
||||||
|
"id": "8000001",
|
||||||
|
"ril100": "KA",
|
||||||
|
"name": "Aachen Hbf",
|
||||||
|
"weight": 653.75,
|
||||||
|
"location": { /* … */ },
|
||||||
|
"operator": { /* … */ },
|
||||||
|
"address": { /* … */ },
|
||||||
|
// …
|
||||||
|
},
|
||||||
|
// …
|
||||||
|
}
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
\`\`\`shell
|
||||||
|
# filter db-stations by \`hasDBLounge\` property, get newline-delimited JSON
|
||||||
|
curl 'https://v5.db.transport.rest/stations?hasDBLounge=true' -H 'accept: application/x-ndjson' -s | jq
|
||||||
|
\`\`\`
|
||||||
|
`,
|
||||||
|
'/stations/:id': `\
|
||||||
|
### Example
|
||||||
|
|
||||||
|
\`\`\`shell
|
||||||
|
# lookup Halle (Saale) Hbf
|
||||||
|
curl 'https://v5.db.transport.rest/stations/8010159' -s | jq
|
||||||
|
curl 'https://v5.db.transport.rest/stations/LH' -s | jq # RIL100/DS100
|
||||||
|
curl 'https://v5.db.transport.rest/stations/LHG' -s | jq # RIL100/DS100
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
\`\`\`js
|
||||||
|
{
|
||||||
|
"type": "station",
|
||||||
|
"id": "8010159",
|
||||||
|
"additionalIds": ["8098159"],
|
||||||
|
"ril100": "LH",
|
||||||
|
"nr": 2498,
|
||||||
|
"name": "Halle (Saale) Hbf",
|
||||||
|
"weight": 815.6,
|
||||||
|
"location": { /* … */ },
|
||||||
|
"operator": { /* … */ },
|
||||||
|
"address": { /* … */ },
|
||||||
|
"ril100Identifiers": [
|
||||||
|
{
|
||||||
|
"rilIdentifier": "LH",
|
||||||
|
// …
|
||||||
|
},
|
||||||
|
// …
|
||||||
|
],
|
||||||
|
// …
|
||||||
|
}
|
||||||
|
\`\`\`
|
||||||
|
`,
|
||||||
|
'/stops/:id/departures': `\
|
||||||
|
### Example
|
||||||
|
|
||||||
|
\`\`\`shell
|
||||||
|
# at Halle (Saale) Hbf, in direction Berlin Südkreuz
|
||||||
|
curl 'https://v5.db.transport.rest/stops/8010159/departures?direction=8011113&duration=120' -s | jq
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
\`\`\`js
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"tripId": "1|317591|0|80|1052020",
|
||||||
|
"direction": "Berlin Hbf (tief)",
|
||||||
|
"line": {
|
||||||
|
"type": "line",
|
||||||
|
"id": "ice-702",
|
||||||
|
"name": "ICE 702",
|
||||||
|
"mode": "train",
|
||||||
|
"product": "nationalExpress",
|
||||||
|
// …
|
||||||
|
},
|
||||||
|
|
||||||
|
"when": "2020-05-01T21:06:00+02:00",
|
||||||
|
"plannedWhen": "2020-05-01T21:06:00+02:00",
|
||||||
|
"delay": 0,
|
||||||
|
"platform": "8",
|
||||||
|
"plannedPlatform": "8",
|
||||||
|
|
||||||
|
"stop": {
|
||||||
|
"type": "stop",
|
||||||
|
"id": "8010159",
|
||||||
|
"name": "Halle (Saale) Hbf",
|
||||||
|
"location": { /* … */ },
|
||||||
|
"products": { /* … */ },
|
||||||
|
},
|
||||||
|
|
||||||
|
"remarks": [],
|
||||||
|
// …
|
||||||
|
}
|
||||||
|
]
|
||||||
|
\`\`\`
|
||||||
|
`,
|
||||||
|
'/stops/:id/arrivals': `\
|
||||||
|
### Example
|
||||||
|
|
||||||
|
\`\`\`shell
|
||||||
|
# at Halle (Saale) Hbf, 10 minutes
|
||||||
|
curl 'https://v5.db.transport.rest/stops/8010159/arrivals?duration=10' -s | jq
|
||||||
|
\`\`\`
|
||||||
|
`,
|
||||||
|
'/journeys': `\
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
\`\`\`shell
|
||||||
|
# stop/station to POI
|
||||||
|
curl 'https://v5.db.transport.rest/journeys?from=8010159&to.id=991561765&to.latitude=51.483641&to.longitude=11.980841' -s | jq
|
||||||
|
# without buses, with ticket info
|
||||||
|
curl 'https://v5.db.transport.rest/journeys?from=…&to=…&bus=false&tickets=true' -s | jq
|
||||||
|
\`\`\`
|
||||||
|
`,
|
||||||
|
'/journeys/:ref': `\
|
||||||
|
### Example
|
||||||
|
|
||||||
|
\`\`\`shell
|
||||||
|
# get the refreshToken of a journey
|
||||||
|
journey=$(curl 'https://v5.db.transport.rest/journeys?from=…&to=…&results=1' -s | jq '.journeys[0]')
|
||||||
|
refresh_token=$(echo $journey | jq -r '.refreshToken')
|
||||||
|
|
||||||
|
# refresh the journey
|
||||||
|
curl "https://v5.db.transport.rest/journeys/$(echo $refresh_token | url-encode)" -s | jq
|
||||||
|
\`\`\`
|
||||||
|
`,
|
||||||
|
'/trips/:id': `\
|
||||||
|
### Example
|
||||||
|
|
||||||
|
\`\`\`shell
|
||||||
|
# get the trip ID of a journey leg
|
||||||
|
journey=$(curl 'https://v5.db.transport.rest/journeys?from=…&to=…&results=1' -s | jq '.journeys[0]')
|
||||||
|
journey_leg=$(echo $journey | jq -r '.legs[0]')
|
||||||
|
trip_id=$(echo $journey_leg | jq -r '.tripId')
|
||||||
|
|
||||||
|
# fetch the trip
|
||||||
|
curl "https://v5.db.transport.rest/trips/$(echo $trip_id | url-encode)" -s | jq
|
||||||
|
\`\`\`
|
||||||
|
`,
|
||||||
|
'/radar': `\
|
||||||
|
### Example
|
||||||
|
|
||||||
|
\`\`\`shell
|
||||||
|
bbox='north=53.555&west=9.989&south=53.55&east=10.001'
|
||||||
|
curl "https://v5.db.transport.rest/radar?$bbox&results=10" -s | jq
|
||||||
|
\`\`\`
|
||||||
|
`,
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
listOfRoutes,
|
||||||
|
routes,
|
||||||
|
tail,
|
||||||
|
} = generateApiDocs(api.routes)
|
||||||
|
|
||||||
|
const sortedRoutes = Object.entries(routes)
|
||||||
|
.sort(([routeA], [routeB]) => {
|
||||||
|
const iA = order.indexOf(routeA)
|
||||||
|
const iB = order.indexOf(routeB)
|
||||||
|
if (iA >= 0 && iB >= 0) return iA - iB
|
||||||
|
if (iA < 0 && iB >= 0) return 1
|
||||||
|
if (iB < 0 && iA >= 0) return -1
|
||||||
|
return 0
|
||||||
|
})
|
||||||
|
|
||||||
|
const write = process.stdout.write.bind(process.stdout)
|
||||||
|
|
||||||
|
write(HEAD)
|
||||||
|
write(`\n\n`)
|
||||||
|
|
||||||
|
write(listOfRoutes)
|
||||||
|
write(`\n\n`)
|
||||||
|
|
||||||
|
for (const [route, params] of sortedRoutes) {
|
||||||
|
write(`## \`GET ${route}\`\n\n`)
|
||||||
|
write(descriptions[route] || '')
|
||||||
|
write(`
|
||||||
|
### Query Parameters
|
||||||
|
`)
|
||||||
|
write(params)
|
||||||
|
if (examples[route]) {
|
||||||
|
write('\n' + examples[route])
|
||||||
|
}
|
||||||
|
write(`\n\n`)
|
||||||
|
}
|
||||||
|
write(tail)
|
42
api.js
Normal file
42
api.js
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const createHafas = require('db-hafas')
|
||||||
|
const createApi = require('hafas-rest-api')
|
||||||
|
const createHealthCheck = require('hafas-client-health-check')
|
||||||
|
|
||||||
|
const pkg = require('./package.json')
|
||||||
|
const stations = require('./routes/stations')
|
||||||
|
const station = require('./routes/station')
|
||||||
|
|
||||||
|
const hafas = createHafas(pkg.name)
|
||||||
|
|
||||||
|
const berlinHbf = '8011160'
|
||||||
|
const healthCheck = createHealthCheck(hafas, berlinHbf)
|
||||||
|
|
||||||
|
const modifyRoutes = (routes) => {
|
||||||
|
routes['/stations/:id'] = station
|
||||||
|
routes['/stations'] = stations
|
||||||
|
return routes
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
hostname: process.env.HOSTNAME || 'localhost',
|
||||||
|
port: process.env.PORT ? parseInt(process.env.PORT) : 3000,
|
||||||
|
name: pkg.name,
|
||||||
|
description: pkg.description,
|
||||||
|
homepage: pkg.homepage,
|
||||||
|
version: pkg.version,
|
||||||
|
docsLink: 'https://github.com/derhuerst/db-rest/blob/5/docs/readme.md',
|
||||||
|
logging: true,
|
||||||
|
aboutPage: true,
|
||||||
|
etags: 'strong',
|
||||||
|
healthCheck,
|
||||||
|
modifyRoutes,
|
||||||
|
}
|
||||||
|
|
||||||
|
const api = createApi(hafas, config, () => {})
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
config,
|
||||||
|
api,
|
||||||
|
}
|
650
docs/api.md
650
docs/api.md
|
@ -1,228 +1,610 @@
|
||||||
# [*Deutsche Bahn*](https://en.wikipedia.org/wiki/Deutsche_Bahn) Public Transport API
|
# `v5.db.transport.rest` API documentation
|
||||||
|
|
||||||
**The public endpoint is [`2.db.transport.rest`](`https://2.db.transport.rest`).** This API returns data in the [*Friendly Public Transport Format* `1.2.0`](https://github.com/public-transport/friendly-public-transport-format/blob/1.2.0/spec/readme.md).
|
[`v5.db.transport.rest`](https://v5.db.transport.rest/) is a [REST API](https://restfulapi.net). Data is being returned as [JSON](https://www.json.org/).
|
||||||
|
|
||||||
*Note:* In order to improve this API, I would like to know which software projects use it. Please send an **`X-Identifier` header (e.g. `my-awesome-tool`) to let me know who you are**. I you don't provide it, a hash of the client IP will be logged.
|
You can just use the API without authentication. There's a [rate limit](https://apisyouwonthate.com/blog/what-is-api-rate-limiting-all-about) of 100 request/minute (burst 200 requests/minute) set up.
|
||||||
|
|
||||||
## all routes
|
*Note:* For [URL-encoding](https://de.wikipedia.org/wiki/URL-Encoding), this documentation uses the `url-encode` tool of the [`url-decode-encode-cli` package](https://www.npmjs.com/package/url-decode-encode-cli).
|
||||||
|
|
||||||
- [`GET /stations?query=…`](#get-stationsquery)
|
|
||||||
- [`GET /stations`](#get-stations)
|
## Routes
|
||||||
- [`GET /stations/:id/departures`](#get-stationsiddepartures)
|
|
||||||
|
*Note:* These routes only wrap [`hafas-client@5` methods](https://github.com/public-transport/hafas-client/blob/5/docs/readme.md), check their docs for more details.
|
||||||
|
|
||||||
|
|
||||||
|
- [`GET /stops/nearby`](#get-stopsnearby)
|
||||||
|
- [`GET /stops/reachable-from`](#get-stopsreachable-from)
|
||||||
|
- [`GET /stops/:id`](#get-stopsid)
|
||||||
|
- [`GET /stops/:id/departures`](#get-stopsiddepartures)
|
||||||
|
- [`GET /stops/:id/arrivals`](#get-stopsidarrivals)
|
||||||
- [`GET /journeys`](#get-journeys)
|
- [`GET /journeys`](#get-journeys)
|
||||||
- [`GET /journeys/:ref`](#get-journeysref)
|
|
||||||
- [`GET /trips/:id`](#get-tripsid)
|
- [`GET /trips/:id`](#get-tripsid)
|
||||||
- [`GET /locations`](#get-locations)
|
- [`GET /locations`](#get-locations)
|
||||||
|
- [`GET /radar`](#get-radar)
|
||||||
|
- [`GET /journeys/:ref`](#get-journeysref)
|
||||||
|
- [`GET /stations/:id`](#get-stationsid)
|
||||||
|
- [`GET /stations`](#get-stations)
|
||||||
|
- [date/time parameters](#datetime-parameters)
|
||||||
|
|
||||||
## `GET /stations?query=…`
|
|
||||||
|
|
||||||
Passes all parameters into [`db-stations-autocomplete`](https://github.com/derhuerst/db-stations-autocomplete).
|
## `GET /locations`
|
||||||
|
|
||||||
- `query`: **Required.**
|
Uses [`hafasClient.locations()`](https://github.com/public-transport/hafas-client/blob/5/docs/locations.md) to **find stops/stations, POIs and addresses matching `query`**.
|
||||||
- `completion`: `true`/`false` – Default is `true`
|
|
||||||
- `fuzzy`: `true`/`false` – Default is `false`
|
|
||||||
|
|
||||||
`Content-Type`: `application/json`
|
### Query Parameters
|
||||||
|
|
||||||
### examples
|
parameter | description | type | default value
|
||||||
|
----------|-------------|------|--------------
|
||||||
|
`query` | **Required.** | string | –
|
||||||
|
`fuzzy` | Find more than exact matches? | boolean | `true`
|
||||||
|
`results` | How many stations shall be shown? | number | `10`
|
||||||
|
`stops` | Show stops/stations? | boolean | `true`
|
||||||
|
`addresses` | Show points of interest? | boolean | `true`
|
||||||
|
`poi` | Show addresses? | boolean | `true`
|
||||||
|
`linesOfStops` | Parse & return lines of each stop/station? | boolean | `false`
|
||||||
|
`language` | Language of the results. | string | `en`
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
curl 'https://2.db.transport.rest/stations?query=jungfernheide'
|
curl 'https://v5.db.transport.rest/locations?query=halle&results=1' -s | jq
|
||||||
# note the typo
|
```
|
||||||
curl 'https://2.db.transport.rest/stations?query=jungfernhiede&fuzzy=true'
|
|
||||||
|
```js
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "stop",
|
||||||
|
"id": "8010159",
|
||||||
|
"name": "Halle (Saale) Hbf",
|
||||||
|
"location": {
|
||||||
|
"type": "location",
|
||||||
|
"id": "8010159",
|
||||||
|
"latitude": 51.477079,
|
||||||
|
"longitude": 11.98699
|
||||||
|
},
|
||||||
|
"products": {
|
||||||
|
"nationalExpress": true,
|
||||||
|
"national": true,
|
||||||
|
// …
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## `GET /stations`
|
## `GET /stops/nearby`
|
||||||
|
|
||||||
Passes all parameters into [`db-stations`](https://github.com/derhuerst/db-stations).
|
Uses [`hafasClient.nearby()`](https://github.com/public-transport/hafas-client/blob/5/docs/nearby.md) to **find stops/stations close to the given geolocation**.
|
||||||
|
|
||||||
- `id`: Filter by ID.
|
### Query Parameters
|
||||||
- `name`: Filter by name.
|
|
||||||
- `coordinates.latitude`: Filter by latitude.
|
|
||||||
- `coordinates.longitude`: Filter by longitude.
|
|
||||||
- `weight`: Filter by weight.
|
|
||||||
|
|
||||||
`Content-Type`: [`application/x-ndjson`](http://ndjson.org/)
|
parameter | description | type | default value
|
||||||
|
----------|-------------|------|--------------
|
||||||
|
`latitude` | **Required.** | number | –
|
||||||
|
`longitude` | **Required.** | number | –
|
||||||
|
`results` | maximum number of results | number | `8`
|
||||||
|
`distance` | maximum walking distance in meters | number | –
|
||||||
|
`stops` | Return stops/stations? | boolean | `true`
|
||||||
|
`poi` | Return points of interest? | boolean | `false`
|
||||||
|
`linesOfStops` | Parse & expose lines at each stop/station? | boolean | `false`
|
||||||
|
`language` | Language of the results. | string | `en`
|
||||||
|
|
||||||
### examples
|
### Example
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
curl 'https://2.db.transport.rest/stations?name=hannover&coordinates.latitude=52.3765387'
|
curl 'https://v5.db.transport.rest/stops/nearby?latitude=53.5711&longitude=10.0015' -s | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "stop",
|
||||||
|
"id": "694800",
|
||||||
|
"name": "Böttgerstraße, Hamburg",
|
||||||
|
"location": {
|
||||||
|
"type": "location",
|
||||||
|
"id": "694800",
|
||||||
|
"latitude": 53.568356,
|
||||||
|
"longitude": 9.995528
|
||||||
|
},
|
||||||
|
"products": { /* … */ },
|
||||||
|
"distance": 498,
|
||||||
|
},
|
||||||
|
// …
|
||||||
|
{
|
||||||
|
"type": "stop",
|
||||||
|
"id": "694802",
|
||||||
|
"name": "Bahnhof Dammtor, Hamburg",
|
||||||
|
"location": {
|
||||||
|
"type": "location",
|
||||||
|
"id": "694802",
|
||||||
|
"latitude": 53.561048,
|
||||||
|
"longitude": 9.990315
|
||||||
|
},
|
||||||
|
"products": { /* … */ },
|
||||||
|
"distance": 1340,
|
||||||
|
},
|
||||||
|
// …
|
||||||
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## `GET /stations/all`
|
## `GET /stops/reachable-from`
|
||||||
|
|
||||||
Dumps `full.json` from [`db-stations`](https://github.com/derhuerst/db-stations).
|
Uses [`hafasClient.reachableFrom()`](https://github.com/public-transport/hafas-client/blob/5/docs/reachable-from.md) to **find stops/stations reachable within a certain time from an address**.
|
||||||
|
|
||||||
`Content-Type`: `application/json`
|
### Query Parameters
|
||||||
|
|
||||||
### examples
|
parameter | description | type | default value
|
||||||
|
----------|-------------|------|--------------
|
||||||
|
`latitude` | **Required.** | number | –
|
||||||
|
`longitude` | **Required.** | number | –
|
||||||
|
`address` | **Required.** | string | –
|
||||||
|
`when` | Date & time to compute the reachability for. See [date/time parameters](#datetime-parameters). | date+time | *now*
|
||||||
|
`maxTransfers` | Maximum number of transfers. | number | `5`
|
||||||
|
`maxDuration` | Maximum travel duration, in minutes. | number | *infinite*
|
||||||
|
`language` | Language of the results. | string | `en`
|
||||||
|
`nationalExpress` | Include InterCityExpress (ICE)? | boolean | `true`
|
||||||
|
`national` | Include InterCity & EuroCity (IC/EC)? | boolean | `true`
|
||||||
|
`regionalExp` | Include RegionalExpress & InterRegio (RE/IR)? | boolean | `true`
|
||||||
|
`regional` | Include Regio (RB)? | boolean | `true`
|
||||||
|
`suburban` | Include S-Bahn (S)? | boolean | `true`
|
||||||
|
`bus` | Include Bus (B)? | boolean | `true`
|
||||||
|
`ferry` | Include Ferry (F)? | boolean | `true`
|
||||||
|
`subway` | Include U-Bahn (U)? | boolean | `true`
|
||||||
|
`tram` | Include Tram (T)? | boolean | `true`
|
||||||
|
`taxi` | Include Group Taxi (Taxi)? | boolean | `true`
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
curl 'https://2.db.transport.rest/stations/all'
|
curl 'https://v5.db.transport.rest/stops/reachable-from?latitude=53.553766&longitude=9.977514&address=Hamburg,+Holstenwall+9' -s | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"duration": 1,
|
||||||
|
"stations": [
|
||||||
|
{
|
||||||
|
"type": "stop",
|
||||||
|
"id": "694815",
|
||||||
|
"name": "Handwerkskammer, Hamburg",
|
||||||
|
"location": { /* … */ },
|
||||||
|
"products": { /* … */ },
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
// …
|
||||||
|
{
|
||||||
|
"duration": 5,
|
||||||
|
"stations": [
|
||||||
|
{
|
||||||
|
"type": "stop",
|
||||||
|
"id": "694807",
|
||||||
|
"name": "Feldstraße (U), Hamburg",
|
||||||
|
"location": { /* … */ },
|
||||||
|
"products": { /* … */ },
|
||||||
|
// …
|
||||||
|
},
|
||||||
|
// …
|
||||||
|
]
|
||||||
|
},
|
||||||
|
// …
|
||||||
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## `GET /stations/:id/departures`
|
## `GET /stops/:id`
|
||||||
|
|
||||||
Returns departures at a station.
|
Uses [`hafasClient.stop()`](https://github.com/public-transport/hafas-client/blob/5/docs/stop.md) to **find a stop/station by ID**.
|
||||||
|
|
||||||
*Note:* As stated in the [*Friendly Public Transport Format* `1.2.0`](https://github.com/public-transport/friendly-public-transport-format/tree/1.2.0), the returned `departure` and `arrival` times include the current delay.
|
### Query Parameters
|
||||||
|
|
||||||
Passes all parameters into [`departures(…)` from `db-hafas`](https://github.com/public-transport/db-hafas/blob/master/docs/departures.md).
|
parameter | description | type | default value
|
||||||
|
----------|-------------|------|--------------
|
||||||
|
`linesOfStops` | Parse & expose lines at each stop/station? | boolean | `false`
|
||||||
|
`language` | Language of the results. | string | `en`
|
||||||
|
|
||||||
- `when`: A [UNIX timestamp](https://en.wikipedia.org/wiki/Unix_time) or anything parsable by [`parse-messy-time`](https://github.com/substack/parse-messy-time#example). Default: now.
|
### Example
|
||||||
- `duration`: Show departures for the next `n` minutes. Default: `10`.
|
|
||||||
|
|
||||||
`Content-Type`: `application/json`
|
|
||||||
|
|
||||||
### examples
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
curl 'https://2.db.transport.rest/stations/008011160/departures?when=tomorrow%206pm'
|
curl 'https://v5.db.transport.rest/stops/8010159' -s | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
"type": "stop",
|
||||||
|
"id": "8010159",
|
||||||
|
"ids": {
|
||||||
|
"dhid": "de:15002:8010159",
|
||||||
|
"MDV": "8010159",
|
||||||
|
"NASA": "8010159"
|
||||||
|
},
|
||||||
|
"name": "Halle (Saale) Hbf",
|
||||||
|
"location": {
|
||||||
|
"type": "location",
|
||||||
|
"id": "8010159",
|
||||||
|
"latitude": 51.477079,
|
||||||
|
"longitude": 11.98699
|
||||||
|
},
|
||||||
|
"products": { /* … */ },
|
||||||
|
// …
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## `GET /stops/:id/departures`
|
||||||
|
|
||||||
|
Uses [`hafasClient.departures()`](https://github.com/public-transport/hafas-client/blob/5/docs/departures.md) to **get departures at a stop/station**.
|
||||||
|
|
||||||
|
### Query Parameters
|
||||||
|
|
||||||
|
parameter | description | type | default value
|
||||||
|
----------|-------------|------|--------------
|
||||||
|
`when` | Date & time to get departures for. See [date/time parameters](#datetime-parameters). | date+time | *now*
|
||||||
|
`direction` | Filter departures by direction. | string |
|
||||||
|
`duration` | Show departures for how many minutes? | number | `10`
|
||||||
|
`results` | Max. number of departures. | number | *whatever HAFAS wants
|
||||||
|
`linesOfStops` | Parse & return lines of each stop/station? | boolean | `false`
|
||||||
|
`remarks` | Parse & return hints & warnings? | boolean | `true`
|
||||||
|
`language` | Language of the results. | string | `en`
|
||||||
|
`includeRelatedStations` | Fetch departures at related stops, e.g. those that belong together on the metro map? | boolean | `true`
|
||||||
|
`stopovers` | Fetch & parse next stopovers of each departure? | boolean | `false`
|
||||||
|
`nationalExpress` | Include InterCityExpress (ICE)? | boolean | `true`
|
||||||
|
`national` | Include InterCity & EuroCity (IC/EC)? | boolean | `true`
|
||||||
|
`regionalExp` | Include RegionalExpress & InterRegio (RE/IR)? | boolean | `true`
|
||||||
|
`regional` | Include Regio (RB)? | boolean | `true`
|
||||||
|
`suburban` | Include S-Bahn (S)? | boolean | `true`
|
||||||
|
`bus` | Include Bus (B)? | boolean | `true`
|
||||||
|
`ferry` | Include Ferry (F)? | boolean | `true`
|
||||||
|
`subway` | Include U-Bahn (U)? | boolean | `true`
|
||||||
|
`tram` | Include Tram (T)? | boolean | `true`
|
||||||
|
`taxi` | Include Group Taxi (Taxi)? | boolean | `true`
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# at Halle (Saale) Hbf, in direction Berlin Südkreuz
|
||||||
|
curl 'https://v5.db.transport.rest/stops/8010159/departures?direction=8011113&duration=120' -s | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"tripId": "1|317591|0|80|1052020",
|
||||||
|
"direction": "Berlin Hbf (tief)",
|
||||||
|
"line": {
|
||||||
|
"type": "line",
|
||||||
|
"id": "ice-702",
|
||||||
|
"name": "ICE 702",
|
||||||
|
"mode": "train",
|
||||||
|
"product": "nationalExpress",
|
||||||
|
// …
|
||||||
|
},
|
||||||
|
|
||||||
|
"when": "2020-05-01T21:06:00+02:00",
|
||||||
|
"plannedWhen": "2020-05-01T21:06:00+02:00",
|
||||||
|
"delay": 0,
|
||||||
|
"platform": "8",
|
||||||
|
"plannedPlatform": "8",
|
||||||
|
|
||||||
|
"stop": {
|
||||||
|
"type": "stop",
|
||||||
|
"id": "8010159",
|
||||||
|
"name": "Halle (Saale) Hbf",
|
||||||
|
"location": { /* … */ },
|
||||||
|
"products": { /* … */ },
|
||||||
|
},
|
||||||
|
|
||||||
|
"remarks": [],
|
||||||
|
// …
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## `GET /stops/:id/arrivals`
|
||||||
|
|
||||||
|
Works like [`/stops/:id/departures`](#get-stopsiddepartures), except that it uses [`hafasClient.arrivals()`](https://github.com/public-transport/hafas-client/blob/5/docs/arrivals.md) to **arrivals at a stop/station**.
|
||||||
|
|
||||||
|
### Query Parameters
|
||||||
|
|
||||||
|
parameter | description | type | default value
|
||||||
|
----------|-------------|------|--------------
|
||||||
|
`when` | Date & time to get departures for. See [date/time parameters](#datetime-parameters). | date+time | *now*
|
||||||
|
`direction` | Filter departures by direction. | string |
|
||||||
|
`duration` | Show departures for how many minutes? | number | `10`
|
||||||
|
`results` | Max. number of departures. | number | *whatever HAFAS wants*
|
||||||
|
`linesOfStops` | Parse & return lines of each stop/station? | boolean | `false`
|
||||||
|
`remarks` | Parse & return hints & warnings? | boolean | `true`
|
||||||
|
`language` | Language of the results. | string | `en`
|
||||||
|
`includeRelatedStations` | Fetch departures at related stops, e.g. those that belong together on the metro map? | boolean | `true`
|
||||||
|
`stopovers` | Fetch & parse next stopovers of each departure? | boolean | `false`
|
||||||
|
`nationalExpress` | Include InterCityExpress (ICE)? | boolean | `true`
|
||||||
|
`national` | Include InterCity & EuroCity (IC/EC)? | boolean | `true`
|
||||||
|
`regionalExp` | Include RegionalExpress & InterRegio (RE/IR)? | boolean | `true`
|
||||||
|
`regional` | Include Regio (RB)? | boolean | `true`
|
||||||
|
`suburban` | Include S-Bahn (S)? | boolean | `true`
|
||||||
|
`bus` | Include Bus (B)? | boolean | `true`
|
||||||
|
`ferry` | Include Ferry (F)? | boolean | `true`
|
||||||
|
`subway` | Include U-Bahn (U)? | boolean | `true`
|
||||||
|
`tram` | Include Tram (T)? | boolean | `true`
|
||||||
|
`taxi` | Include Group Taxi (Taxi)? | boolean | `true`
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# at Halle (Saale) Hbf, 10 minutes
|
||||||
|
curl 'https://v5.db.transport.rest/stops/8010159/arrivals?duration=10' -s | jq
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## `GET /journeys`
|
## `GET /journeys`
|
||||||
|
|
||||||
Output from [`require('db-hafas').journeys(…)`](https://github.com/public-transport/db-hafas#getting-started). Start location and end location must be either in [station format](#station-format) or in [POI/address format](#poiaddress-format) (you can mix them).
|
Uses [`hafasClient.journeys()`](https://github.com/public-transport/hafas-client/blob/5/docs/journeys.md) to **find journeys from A (`from`) to B (`to`)**.
|
||||||
|
|
||||||
*Note:* As stated in the [*Friendly Public Transport Format* `1.2.0`](https://github.com/public-transport/friendly-public-transport-format/tree/1.2.0), the returned `departure` and `arrival` times include the current delay.
|
`from` (A), `to` (B), and the optional `via` must each have one of these formats:
|
||||||
|
|
||||||
## station format
|
- as stop/station ID (e.g. `from=8010159` for *Halle (Saale) Hbf*)
|
||||||
|
- as a POI (e.g. `from.id=991561765&from.latitude=51.48364&from.longitude=11.98084` for *Halle+(Saale),+Stadtpark+Halle+(Grünanlagen)*)
|
||||||
|
- as an address (e.g. `from.latitude=51.25639&from.longitude=7.46685&from.address=Hansestadt+Breckerfeld,+Hansering+3` for *Hansestadt Breckerfeld, Hansering 3*)
|
||||||
|
|
||||||
- `from`: **Required.** Station ID (e.g. `008011162`).
|
### Pagination
|
||||||
- `to`: **Required.** Station ID (e.g. `008011162`).
|
|
||||||
|
|
||||||
## POI format
|
Given a response, you can also fetch more journeys matching the same criteria. Instead of `from*`, `to*` & `departure`/`arrival`, pass `earlierRef` from the first response as `earlierThan` to get journeys "before", or `laterRef` as `laterThan` to get journeys "after".
|
||||||
|
|
||||||
- `from.latitude`/`to.latitude`: **Required.** Latitude (e.g. `52.543333`).
|
Check the [`hafasClient.journeys()` docs](https://github.com/public-transport/hafas-client/blob/5/docs/journeys.md) for more details.
|
||||||
- `from.longitude`/`to.longitude`: **Required.** Longitude (e.g. `13.351686`).
|
|
||||||
- `from.name`/`to.name`: Name of the locality (e.g. `Atze Musiktheater`).
|
|
||||||
- `from.id`/`to.id`: **Required.** POI ID (e.g. `991598902`).
|
|
||||||
|
|
||||||
## address format
|
### Query Parameters
|
||||||
|
|
||||||
- `from.latitude`/`to.latitude`: **Required.** Latitude (e.g. `52.543333`).
|
parameter | description | type | default value
|
||||||
- `from.longitude`/`to.longitude`: **Required.** Longitude (e.g. `13.351686`).
|
----------|-------------|------|--------------
|
||||||
- `from.address`/`to.address`: **Required.** Address (e.g. `Voltastr. 17`).
|
`departure` | Compute journeys departing at this date/time. Mutually exclusive with `arrival`. See [date/time parameters](#datetime-parameters). | date+time | *now*
|
||||||
|
`arrival` | Compute journeys arriving at this date/time. Mutually exclusive with `departure`. See [date/time parameters](#datetime-parameters). | date+time | *now*
|
||||||
|
`earlierThan` | Compute journeys "before" an `ealierRef`. | string |
|
||||||
|
`laterThan` | Compute journeys "after" an `laterRef`. | string |
|
||||||
|
`results` | Max. number of journeys. | number | `3`
|
||||||
|
`stopovers` | Fetch & parse stopovers on the way? | boolean | `false`
|
||||||
|
`transfers` | Maximum number of transfers. | number | *let HAFAS decide*
|
||||||
|
`transferTime` | Minimum time in minutes for a single transfer. | number | `0`
|
||||||
|
`accessibility` | `partial` or `complete`. | string | *not accessible*
|
||||||
|
`bike` | Compute only bike-friendly journeys? | boolean | `false`
|
||||||
|
`startWithWalking` | Consider walking to nearby stations at the beginning of a journey? | boolean | `true`
|
||||||
|
`walkingSpeed` | `slow`, `normal` or `fast`. | string | `normal`
|
||||||
|
`tickets` | Return information about available tickets? | boolean | `false`
|
||||||
|
`polylines` | Fetch & parse a shape for each journey leg? | boolean | `false`
|
||||||
|
`remarks` | Parse & return hints & warnings? | boolean | `true`
|
||||||
|
`scheduledDays` | Parse & return dates each journey is valid on? | boolean | `false`
|
||||||
|
`language` | Language of the results. | string | `en`
|
||||||
|
`nationalExpress` | Include InterCityExpress (ICE)? | boolean | `true`
|
||||||
|
`national` | Include InterCity & EuroCity (IC/EC)? | boolean | `true`
|
||||||
|
`regionalExp` | Include RegionalExpress & InterRegio (RE/IR)? | boolean | `true`
|
||||||
|
`regional` | Include Regio (RB)? | boolean | `true`
|
||||||
|
`suburban` | Include S-Bahn (S)? | boolean | `true`
|
||||||
|
`bus` | Include Bus (B)? | boolean | `true`
|
||||||
|
`ferry` | Include Ferry (F)? | boolean | `true`
|
||||||
|
`subway` | Include U-Bahn (U)? | boolean | `true`
|
||||||
|
`tram` | Include Tram (T)? | boolean | `true`
|
||||||
|
`taxi` | Include Group Taxi (Taxi)? | boolean | `true`
|
||||||
|
|
||||||
## other parameters
|
### Examples
|
||||||
|
|
||||||
- `departure`/`arrival`: A [UNIX timestamp](https://en.wikipedia.org/wiki/Unix_time) or anything parsable by [`parse-messy-time`](https://github.com/substack/parse-messy-time#example). Default: now. Use either `departure` or `arrival`.
|
|
||||||
- `earlierThan`: By passing an identifier from another query, get earlier journeys than before. Mutually exlusive with `laterThan`, `departure` & `arrival`.
|
|
||||||
- `laterThan`: By passing an identifier from another query, get later journeys than before. Mutually exclusive with `earlierThan`, `departure` & `arrival`.
|
|
||||||
- `results`: Maximum number of results. Default: `5`.
|
|
||||||
- `via`: Station ID. Default: `null`.
|
|
||||||
- `stopovers`: Return stations on the way? Default: `false`.
|
|
||||||
- `transfers`: Maximum number of transfers. Default: `5`.
|
|
||||||
- `transferTime`: Minimum time in minutes for a single transfer. Default: `0`.
|
|
||||||
- `accessibility`: Possible values: `partial`, `complete`. Default: `none`.
|
|
||||||
- `bike`: Return only bike-friendly journeys. Default: `false`.
|
|
||||||
- `tickets`: Return information about available tickets. Default: `false`.
|
|
||||||
- `language`: Language to get results in. Default: `en`.
|
|
||||||
- `polylines`: Return a shape for each leg? Default: `false`.
|
|
||||||
- `remarks`: Parse & expose hints & warnings? Default: `true`.
|
|
||||||
- `startWithWalking`: Consider walking to nearby stations at the beginning of a journey? Default: `true`.
|
|
||||||
- `scheduledDays`: Parse which days each journey is valid on? Default: `false`.
|
|
||||||
|
|
||||||
You can filter by means of transportation using these parameters:
|
|
||||||
|
|
||||||
- `taxi`: Include taxis? Default: `false`.
|
|
||||||
- `tram`: Include [trams](https://en.wikipedia.org/wiki/Tram)? Default: `true`.
|
|
||||||
- `ferry`: Include [ferries](https://en.wikipedia.org/wiki/Ferry)? Default: `true`.
|
|
||||||
- `bus`: Include [buses](https://en.wikipedia.org/wiki/Bus)? Default: `true`.
|
|
||||||
- `subway`: Include [U-Bahn trains](https://en.wikipedia.org/wiki/Rapid_transit)? Default: `true`.
|
|
||||||
- `suburban`: Include [S-Bahn trains](https://en.wikipedia.org/wiki/S-train)? Default: `true`.
|
|
||||||
- `regional`: Include RB/ODEG trains? Default: `true`.
|
|
||||||
- `regionalExp`: Include RE/ODEG trains? Default: `true`.
|
|
||||||
- `national`: Include [IC/EC trains](https://en.wikipedia.org/wiki/Intercity_(Deutsche_Bahn)? Default: `true`.
|
|
||||||
- `nationalExp`: Include [ICE trains](https://en.wikipedia.org/wiki/Intercity-Express)? Default: `true`.
|
|
||||||
|
|
||||||
`Content-Type`: `application/json`
|
|
||||||
|
|
||||||
### examples
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
curl 'https://2.db.transport.rest/journeys?from=008011162&to=008000281'
|
# stop/station to POI
|
||||||
curl 'https://2.db.transport.rest/journeys?from=008004158&to.id=991598902&to.name=Atze%20Musiktheater&to.latitude=52.543333&to.longitude=13.351686'
|
curl 'https://v5.db.transport.rest/journeys?from=8010159&to.id=991561765&to.latitude=51.483641&to.longitude=11.980841' -s | jq
|
||||||
curl 'https://2.db.transport.rest/journeys?from=…&to=…&results=3&bus=false&tickets=true'
|
# without buses, with ticket info
|
||||||
|
curl 'https://v5.db.transport.rest/journeys?from=…&to=…&bus=false&tickets=true' -s | jq
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## `GET /journeys/:ref`
|
## `GET /journeys/:ref`
|
||||||
|
|
||||||
Output from [`hafas.refreshJourney(…)`](https://github.com/public-transport/hafas-client/blob/4/docs/refresh-journey.md).
|
Uses [`hafasClient.refreshJourney()`](https://github.com/public-transport/hafas-client/blob/5/docs/refresh-journey.md) to **"refresh" a journey, using its `refreshToken`**.
|
||||||
|
|
||||||
- `stopovers`: Return stations on the way? Default: `false`.
|
The journey will be the same (equal `from`, `to`, `via`, date/time & vehicles used), but you can get up-to-date realtime data, like delays & cancellations.
|
||||||
- `polylines`: Return shape of each journey leg? Default: `false`.
|
|
||||||
- `remarks`: Parse & expose hints & warnings? Default: `true`.
|
|
||||||
- `language`: Language of the results. Default: `en`.
|
|
||||||
|
|
||||||
`Content-Type`: `application/json`
|
### Query Parameters
|
||||||
|
|
||||||
### examples
|
parameter | description | type | default value
|
||||||
|
----------|-------------|------|--------------
|
||||||
|
`stopovers` | Fetch & parse stopovers on the way? | boolean | `false`
|
||||||
|
`tickets` | Fetch & parse a shape for each journey leg? | boolean | `false`
|
||||||
|
`polylines` | Return information about available tickets? | boolean | `false`
|
||||||
|
`remarks` | Parse & return hints & warnings? | boolean | `true`
|
||||||
|
`language` | Language of the results. | string | `en`
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
curl 'https://2.db.transport.rest/journeys/%C2%B6HKI%C2%B6T%24A%3D1%40O%3DBerlin%20Hbf%20(tief)%40L%3D8098160%40a%3D128%40%24A%3D1%40O%3DHamburg%20Hbf%40L%3D8002549%40a%3D128%40%24201910062138%24201910062333%24ICE%20%20502%24%241%24%C2%A7T%24A%3D1%40O%3DHamburg%20Hbf%40L%3D8002549%40a%3D128%40%24A%3D1%40O%3DMannheim%20Hbf%40L%3D8000244%40a%3D128%40%24201910062345%24201910070625%24ICE%201271%24%241%24%C2%A7T%24A%3D1%40O%3DMannheim%20Hbf%40L%3D8000244%40a%3D128%40%24A%3D1%40O%3DStuttgart%20Hbf%40L%3D8000096%40a%3D128%40%24201910070629%24201910070707%24ICE%20%20991%24%241%24%C2%A7T%24A%3D1%40O%3DStuttgart%20Hbf%40L%3D8000096%40a%3D128%40%24A%3D1%40O%3DT%C3%BCbingen%20Hbf%40L%3D8000141%40a%3D128%40%24201910070722%24201910070823%24RE%2022011%24%241%24%0A'
|
# get the refreshToken of a journey
|
||||||
|
journey=$(curl 'https://v5.db.transport.rest/journeys?from=…&to=…&results=1' -s | jq '.journeys[0]')
|
||||||
|
refresh_token=$(echo $journey | jq -r '.refreshToken')
|
||||||
|
|
||||||
|
# refresh the journey
|
||||||
|
curl "https://v5.db.transport.rest/journeys/$(echo $refresh_token | url-encode)" -s | jq
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## `GET /trips/:id`
|
## `GET /trips/:id`
|
||||||
|
|
||||||
Output from [`hafas.trip(…)`](https://github.com/public-transport/hafas-client/blob/4/docs/trip.md).
|
Uses [`hafasClient.trip()`](https://github.com/public-transport/hafas-client/blob/5/docs/trip.md) to **fetch a trip by ID**.
|
||||||
|
|
||||||
- `lineName`: **Required.** Line name of the part's mode of transport, e.g. `RE 7`.
|
A trip is a specific vehicle, stopping at a series of stops at specific points in time. Departures, arrivals & journey legs reference trips by their ID.
|
||||||
- `stopovers`: Return stations on the way? Default: `true`.
|
|
||||||
- `remarks`: Parse & expose hints & warnings? Default: `true`.
|
|
||||||
- `polyline`: Return a shape for the trip? Default: `false`.
|
|
||||||
- `language`: Language of the results. Default: `en`.
|
|
||||||
|
|
||||||
`Content-Type`: `application/json`
|
### Query Parameters
|
||||||
|
|
||||||
### examples
|
parameter | description | type | default value
|
||||||
|
----------|-------------|------|--------------
|
||||||
|
`lineName` | **Required.** Line name of the part's mode of transport, e.g. `RE7`. | string | –
|
||||||
|
`stopovers` | Fetch & parse stopovers on the way? | boolean | `true`
|
||||||
|
`remarks` | Parse & return hints & warnings? | boolean | `true`
|
||||||
|
`polyline` | Fetch & parse the geographic shape of the trip? | boolean | `false`
|
||||||
|
`language` | Language of the results. | string | `en`
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
curl 'https://your-api-endpoint/trips/1|229086|0|80|6102019?lineName=ICE+993'
|
# get the trip ID of a journey leg
|
||||||
|
journey=$(curl 'https://v5.db.transport.rest/journeys?from=…&to=…&results=1' -s | jq '.journeys[0]')
|
||||||
|
journey_leg=$(echo $journey | jq -r '.legs[0]')
|
||||||
|
trip_id=$(echo $journey_leg | jq -r '.tripId')
|
||||||
|
|
||||||
|
# fetch the trip
|
||||||
|
curl "https://v5.db.transport.rest/trips/$(echo $trip_id | url-encode)" -s | jq
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## `GET /locations`
|
## `GET /stations`
|
||||||
|
|
||||||
Output from [`require('db-hafas').locations(…)`](https://github.com/public-transport/db-hafas/blob/master/docs/locations.md)
|
If the `query` parameter is used, it will use [`db-stations-autocomplete`](https://npmjs.com/package/db-stations-autocomplete) to autocomplete *Deutsche Bahn*-operated stops/stations. Otherwise, it will filter the stops/stations in [`db-stations`](https://npmjs.com/package/db-stations).
|
||||||
|
|
||||||
- `query`: **Required.** (e.g. `Alexanderplatz`)
|
Instead of receiving a JSON response, you can request [newline-delimited JSON](http://ndjson.org) by sending `Accept: application/x-ndjson`.
|
||||||
- `results`: How many stations shall be shown? Default: `10`.
|
|
||||||
- `stations`: Show stations? Default: `true`.
|
|
||||||
- `poi`: Show points of interest? Default: `true`.
|
|
||||||
- `addresses`: Show addresses? Default: `true`.
|
|
||||||
|
|
||||||
`Content-Type`: `application/json`
|
### Query Parameters
|
||||||
|
|
||||||
### examples
|
parameter | description | type | default value
|
||||||
|
----------|-------------|------|--------------
|
||||||
|
`query` | Find stations by name using [`db-stations-autocomplete`](https://npmjs.com/package/db-stations-autocomplete). | string | –
|
||||||
|
`limit` | *If `query` is used:* Return at most `n` stations. | number | `3`
|
||||||
|
`fuzzy` | *If `query` is used:* Find stations despite typos. | boolean | `false`
|
||||||
|
`completion` | *If `query` is used:* Autocomplete stations. | boolean | `true`
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
curl 'https://2.db.transport.rest/locations?query=Alexanderplatz'
|
# autocomplete using db-stations-autocomplete
|
||||||
curl 'https://2.db.transport.rest/locations?query=Pestalozzistra%C3%9Fe%2082%2C%20Berlin&poi=false&stations=false'
|
curl 'https://v5.db.transport.rest/stations?query=dammt' -s | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
"8002548": {
|
||||||
|
"id": "8002548",
|
||||||
|
"relevance": 0.8572361756428573,
|
||||||
|
"score": 9.175313823998414,
|
||||||
|
"weight": 1212,
|
||||||
|
"type": "station",
|
||||||
|
"ril100": "ADF",
|
||||||
|
"name": "Hamburg Dammtor",
|
||||||
|
"location": {
|
||||||
|
"type": "location",
|
||||||
|
"latitude": 53.560751,
|
||||||
|
"longitude": 9.989566
|
||||||
|
},
|
||||||
|
"operator": {
|
||||||
|
"type": "operator",
|
||||||
|
"id": "hamburger-verkehrsverbund-gmbh",
|
||||||
|
"name": "BWVI"
|
||||||
|
},
|
||||||
|
"address": {
|
||||||
|
"city": "Hamburg",
|
||||||
|
"zipcode": "20354",
|
||||||
|
"street": "Dag-Hammarskjöld-Platz 15"
|
||||||
|
},
|
||||||
|
// …
|
||||||
|
},
|
||||||
|
// …
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# filter db-stations by `hasParking` property
|
||||||
|
curl 'https://v5.db.transport.rest/stations?hasParking=true' -s | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
"8000001": {
|
||||||
|
"type": "station",
|
||||||
|
"id": "8000001",
|
||||||
|
"ril100": "KA",
|
||||||
|
"name": "Aachen Hbf",
|
||||||
|
"weight": 653.75,
|
||||||
|
"location": { /* … */ },
|
||||||
|
"operator": { /* … */ },
|
||||||
|
"address": { /* … */ },
|
||||||
|
// …
|
||||||
|
},
|
||||||
|
// …
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# filter db-stations by `hasDBLounge` property, get newline-delimited JSON
|
||||||
|
curl 'https://v5.db.transport.rest/stations?hasDBLounge=true' -H 'accept: application/x-ndjson' -s | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## `GET /stations/:id`
|
||||||
|
|
||||||
|
Returns a stop/station from [`db-stations`](https://npmjs.com/package/db-stations).
|
||||||
|
|
||||||
|
### Query Parameters
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# lookup Halle (Saale) Hbf
|
||||||
|
curl 'https://v5.db.transport.rest/stations/8010159' -s | jq
|
||||||
|
curl 'https://v5.db.transport.rest/stations/LH' -s | jq # RIL100/DS100
|
||||||
|
curl 'https://v5.db.transport.rest/stations/LHG' -s | jq # RIL100/DS100
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
"type": "station",
|
||||||
|
"id": "8010159",
|
||||||
|
"additionalIds": ["8098159"],
|
||||||
|
"ril100": "LH",
|
||||||
|
"nr": 2498,
|
||||||
|
"name": "Halle (Saale) Hbf",
|
||||||
|
"weight": 815.6,
|
||||||
|
"location": { /* … */ },
|
||||||
|
"operator": { /* … */ },
|
||||||
|
"address": { /* … */ },
|
||||||
|
"ril100Identifiers": [
|
||||||
|
{
|
||||||
|
"rilIdentifier": "LH",
|
||||||
|
// …
|
||||||
|
},
|
||||||
|
// …
|
||||||
|
],
|
||||||
|
// …
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## `GET /radar`
|
## `GET /radar`
|
||||||
|
|
||||||
- `north`: **Required.** Northern latitude.
|
Uses [`hafasClient.radar()`](https://github.com/public-transport/hafas-client/blob/5/docs/radar.md) to **find all vehicles currently in an area**, as well as their movements.
|
||||||
- `west`: **Required.** Western longtidue.
|
|
||||||
- `south`: **Required.** Southern latitude.
|
|
||||||
- `east`: **Required.** Eastern longtidue.
|
|
||||||
- `results`: How many vehicles shall be shown? Default: `256`.
|
|
||||||
- `duration`: Compute frames for how many seconds? Default: `30`.
|
|
||||||
- `frames`: Number of frames to compute. Default: `3`.
|
|
||||||
|
|
||||||
`Content-Type`: `application/json`
|
### Query Parameters
|
||||||
|
|
||||||
### examples
|
parameter | description | type | default value
|
||||||
|
----------|-------------|------|--------------
|
||||||
|
`north` | **Required.** Northern latitude. | number | –
|
||||||
|
`west` | **Required.** Western longitude. | number | –
|
||||||
|
`south` | **Required.** Southern latitude. | number | –
|
||||||
|
`east` | **Required.** Eastern longitude. | number | –
|
||||||
|
`results` | Max. number of vehicles. | number | `256`
|
||||||
|
`duration` | Compute frames for the next `n` seconds. | number | `30`
|
||||||
|
`frames` | Number of frames to compute. | number | `3`
|
||||||
|
`polylines` | Fetch & parse a geographic shape for the movement of each vehicle? | boolean | `true`
|
||||||
|
`language` | Language of the results. | string | `en`
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
curl 'https://2.db.transport.rest/radar?north=52.52411&west=13.41002&south=52.51942&east=13.41709'
|
bbox='north=53.555&west=9.989&south=53.55&east=10.001'
|
||||||
|
curl "https://v5.db.transport.rest/radar?$bbox&results=10" -s | jq
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Date/Time Parameters
|
||||||
|
|
||||||
|
Possible formats:
|
||||||
|
|
||||||
|
- anything that [`parse-human-relative-time`](https://npmjs.com/package/parse-human-relative-time) can parse (e.g. `tomorrow 2pm`)
|
||||||
|
- [ISO 8601 date/time string](https://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations) (e.g. `2020-04-26T22:43+02:00`)
|
||||||
|
- [UNIX timestamp](https://en.wikipedia.org/wiki/Unix_time) (e.g. `1587933780`)
|
||||||
|
|
36
index.js
36
index.js
|
@ -1,40 +1,6 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const createHafas = require('db-hafas')
|
const {api, config} = require('./api')
|
||||||
const createApi = require('hafas-rest-api')
|
|
||||||
const createHealthCheck = require('hafas-client-health-check')
|
|
||||||
|
|
||||||
const pkg = require('./package.json')
|
|
||||||
const stations = require('./routes/stations')
|
|
||||||
const station = require('./routes/station')
|
|
||||||
|
|
||||||
const hafas = createHafas(pkg.name)
|
|
||||||
|
|
||||||
const berlinHbf = '8011160'
|
|
||||||
const healthCheck = createHealthCheck(hafas, berlinHbf)
|
|
||||||
|
|
||||||
const modifyRoutes = (routes) => {
|
|
||||||
routes['/stations'] = stations
|
|
||||||
routes['/stations/:id'] = station
|
|
||||||
return routes
|
|
||||||
}
|
|
||||||
|
|
||||||
const config = {
|
|
||||||
hostname: process.env.HOSTNAME || 'localhost',
|
|
||||||
port: process.env.PORT ? parseInt(process.env.PORT) : 3000,
|
|
||||||
name: pkg.name,
|
|
||||||
description: pkg.description,
|
|
||||||
homepage: pkg.homepage,
|
|
||||||
version: pkg.version,
|
|
||||||
docsLink: 'https://github.com/derhuerst/db-rest/blob/5/docs/readme.md',
|
|
||||||
logging: true,
|
|
||||||
aboutPage: true,
|
|
||||||
etags: 'strong',
|
|
||||||
healthCheck,
|
|
||||||
modifyRoutes,
|
|
||||||
}
|
|
||||||
|
|
||||||
const api = createApi(hafas, config, () => {})
|
|
||||||
|
|
||||||
api.listen(config.port, (err) => {
|
api.listen(config.port, (err) => {
|
||||||
const {logger} = api.locals
|
const {logger} = api.locals
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
"pino-pretty": "^4.0.0"
|
"pino-pretty": "^4.0.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"docs": "node api-docs.js >docs/api.md",
|
||||||
|
"build": "npm run docs",
|
||||||
"start": "node index.js"
|
"start": "node index.js"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue