db-rest/api-docs.js
Jannis R 4b333ea9be
prepare for v6 📝💚
2022-12-21 14:47:58 +01:00

457 lines
12 KiB
JavaScript

'use strict'
const generateApiDocs = require('hafas-rest-api/tools/generate-docs')
const {api} = require('./api')
const HEAD = `\
# \`v6.db.transport.rest\` API documentation
[\`v6.db.transport.rest\`](https://v6.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.
[OpenAPI playground](https://petstore.swagger.io/?url=https%3A%2F%2Fv6.db.transport.rest%2F.well-known%2Fservice-desc%0A)
*Note:* The examples snippets in this documentation uses the \`url-encode\` CLI tool of the [\`url-decode-encode-cli\` package](https://www.npmjs.com/package/url-decode-encode-cli) for [URL-encoding](https://de.wikipedia.org/wiki/URL-Encoding).
`
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@2\`](https://github.com/derhuerst/db-stations-autocomplete/tree/2.2.0) to autocomplete *Deutsche Bahn*-operated stops/stations. Otherwise, it will filter the stops/stations in [\`db-stations@3\`](https://github.com/derhuerst/db-stations/tree/3.0.1).
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://v6.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://v6.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://v6.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://v6.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://v6.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://v6.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://v6.db.transport.rest/stations?hasDBLounge=true' -H 'accept: application/x-ndjson' -s | jq
\`\`\`
`,
'/stations/:id': `\
### Example
\`\`\`shell
# lookup Halle (Saale) Hbf
curl 'https://v6.db.transport.rest/stations/8010159' -s | jq
curl 'https://v6.db.transport.rest/stations/LH' -s | jq # RIL100/DS100
curl 'https://v6.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://v6.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://v6.db.transport.rest/stops/8010159/arrivals?duration=10' -s | jq
\`\`\`
`,
'/journeys': `\
### Examples
\`\`\`shell
# stop/station to POI
curl 'https://v6.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://v6.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://v6.db.transport.rest/journeys?from=…&to=…&results=1' -s | jq '.journeys[0]')
refresh_token=$(echo $journey | jq -r '.refreshToken')
# refresh the journey
curl "https://v6.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://v6.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://v6.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://v6.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)