Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: build & publish Docker image
on:
push:
branches:
- 6
- 7
jobs:
lint-test:
name: lint, build & test
Expand All @@ -13,7 +13,7 @@ jobs:
- name: setup Node
uses: actions/setup-node@v4
with:
node-version: 18.x
node-version: 20.x
- run: npm install
- run: npm run lint
- run: npm run build
Expand Down Expand Up @@ -41,7 +41,7 @@ jobs:
push: true
platforms: linux/amd64,linux/arm64
tags: |
derhuerst/vbb-rest:6
derhuerst/vbb-rest:7
derhuerst/vbb-rest:latest
# https://docs.docker.com/build/ci/github-actions/examples/#github-cache
cache-from: type=gha
Expand All @@ -66,8 +66,8 @@ jobs:
push: true
platforms: linux/amd64,linux/arm64
tags: |
ghcr.io/${{github.repository}}:v6
ghcr.io/${{github.repository}}:v6_${{steps.hash.outputs.hash}}_${{steps.datetime.outputs.datetime}}
ghcr.io/${{github.repository}}:v7
ghcr.io/${{github.repository}}:v7_${{steps.hash.outputs.hash}}_${{steps.datetime.outputs.datetime}}
# https://docs.docker.com/build/ci/github-actions/examples/#github-cache
cache-from: type=gha
cache-to: type=gha,mode=max,oci-mediatypes=true,compression=zstd
5 changes: 2 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:18-alpine as builder

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / build & publish Docker image

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / build & publish Docker image

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/
WORKDIR /app

# install dependencies
Expand All @@ -16,9 +16,9 @@
LABEL org.opencontainers.image.title="vbb-rest"
LABEL org.opencontainers.image.description="An HTTP API for Berlin & Brandenburg public transport."
LABEL org.opencontainers.image.authors="Jannis R <mail@jannisr.de>"
LABEL org.opencontainers.image.documentation="https://github.com/derhuerst/vbb-rest/tree/6"
LABEL org.opencontainers.image.documentation="https://github.com/derhuerst/vbb-rest/tree/7"
LABEL org.opencontainers.image.source="https://github.com/derhuerst/vbb-rest"
LABEL org.opencontainers.image.revision="6"
LABEL org.opencontainers.image.revision="7"
LABEL org.opencontainers.image.licenses="ISC"
WORKDIR /app

Expand All @@ -33,7 +33,6 @@

EXPOSE 3000

ENV HOSTNAME v6.vbb.transport.rest
ENV PORT 3000

Check warning on line 36 in Dockerfile

View workflow job for this annotation

GitHub Actions / build & publish Docker image

Legacy key/value format with whitespace separator should not be used

LegacyKeyValueFormat: "ENV key=value" should be used instead of legacy "ENV key value" format More info: https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/

Check warning on line 36 in Dockerfile

View workflow job for this annotation

GitHub Actions / build & publish Docker image

Legacy key/value format with whitespace separator should not be used

LegacyKeyValueFormat: "ENV key=value" should be used instead of legacy "ENV key value" format More info: https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/

CMD ["node", "index.js"]
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ It is recommended that you let `bvg-rest` cache HAFAS responses within a [Redis]

### via Docker

A Docker image [is available as `derhuerst/vbb-rest:6`](https://hub.docker.com/r/derhuerst/vbb-rest:6).
A Docker image [is available as `docker.io/derhuerst/vbb-rest:7`](https://hub.docker.com/r/derhuerst/vbb-rest:7).

```shell
docker run -d -p 3000:3000 derhuerst/vbb-rest:6
docker run -d -p 3000:3000 docker.io/derhuerst/vbb-rest:7
```

*Note:* The Docker image does not contain the Redis server.
Expand All @@ -33,7 +33,7 @@ docker run -d -p 3000:3000 derhuerst/vbb-rest:6
```shell
git clone https://github.com/derhuerst/vbb-rest.git
cd vbb-rest
git checkout 6
git checkout 7
npm install

export HOSTNAME='my-vbb-rest-api.example.org'
Expand Down
7 changes: 5 additions & 2 deletions api.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,10 @@ let hafas = createHafas(
// pkg.name,
// seems like these are being blocked
// require('crypto').randomBytes(10).toString('hex'),
'App/4.5.1 (iPhone; iOS 15.2; Scale/3.00)',
(
process.env.HAFAS_USER_AGENT ||
'App/4.5.1 (iPhone; iOS 15.2; Scale/3.00)'
),
{profile: customVbbProfile},
)
let healthCheck = createHealthCheck(hafas, berlinFriedrichstr)
Expand Down Expand Up @@ -113,7 +116,7 @@ const config = {
description: pkg.description,
version: pkg.version,
homepage: pkg.homepage,
docsLink: 'https://github.com/derhuerst/vbb-rest/blob/6/docs/readme.md',
docsLink: 'https://github.com/derhuerst/vbb-rest/blob/7/docs/readme.md',
openapiSpec: true,
logging: true,
aboutPage: false,
Expand Down
4 changes: 2 additions & 2 deletions architecture.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 22 additions & 22 deletions build/api-docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import {generateApiDocs} from 'hafas-rest-api/tools/generate-docs.js'
import {api} from '../api.js'

const HEAD = `\
# \`v6.vbb.transport.rest\` API documentation
# \`v7.vbb.transport.rest\` API documentation

[\`v6.vbb.transport.rest\`](https://v6.vbb.transport.rest/) is a [REST API](https://restfulapi.net). Data is being returned as [JSON](https://www.json.org/).
[\`v7.vbb.transport.rest\`](https://v7.vbb.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.vbb.transport.rest%2F.well-known%2Fservice-desc%0A)
[OpenAPI playground](https://petstore.swagger.io/?url=https%3A%2F%2Fv7.vbb.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).
`
Expand Down Expand Up @@ -121,7 +121,7 @@ const examples = {
### Example

\`\`\`shell
curl 'https://v6.vbb.transport.rest/locations?query=alexanderplatz&results=1' -s | jq
curl 'https://v7.vbb.transport.rest/locations?query=alexanderplatz&results=1' -s | jq
\`\`\`

\`\`\`js
Expand Down Expand Up @@ -150,7 +150,7 @@ curl 'https://v6.vbb.transport.rest/locations?query=alexanderplatz&results=1' -s
### Example

\`\`\`shell
curl 'https://v6.vbb.transport.rest/locations/nearby?latitude=52.52725&longitude=13.4123' -s | jq
curl 'https://v7.vbb.transport.rest/locations/nearby?latitude=52.52725&longitude=13.4123' -s | jq
\`\`\`

\`\`\`js
Expand Down Expand Up @@ -185,7 +185,7 @@ curl 'https://v6.vbb.transport.rest/locations/nearby?latitude=52.52725&longitude
### Example

\`\`\`shell
curl 'https://v6.vbb.transport.rest/stops/reachable-from?latitude=52.52446&longitude=13.40812&address=10178+Berlin-Mitte,+Münzstr.+12' -s | jq
curl 'https://v7.vbb.transport.rest/stops/reachable-from?latitude=52.52446&longitude=13.40812&address=10178+Berlin-Mitte,+Münzstr.+12' -s | jq
\`\`\`

\`\`\`js
Expand Down Expand Up @@ -234,7 +234,7 @@ curl 'https://v6.vbb.transport.rest/stops/reachable-from?latitude=52.52446&longi
### Example

\`\`\`shell
curl 'https://v6.vbb.transport.rest/stops/900017101' -s | jq
curl 'https://v7.vbb.transport.rest/stops/900017101' -s | jq
\`\`\`

\`\`\`js
Expand All @@ -257,7 +257,7 @@ curl 'https://v6.vbb.transport.rest/stops/900017101' -s | jq

\`\`\`shell
# at U Kottbusser Tor, in direction U Görlitzer Bahnhof
curl 'https://v6.vbb.transport.rest/stops/900013102/departures?direction=900014101&duration=10' -s | jq
curl 'https://v7.vbb.transport.rest/stops/900013102/departures?direction=900014101&duration=10' -s | jq
\`\`\`

\`\`\`js
Expand Down Expand Up @@ -303,15 +303,15 @@ curl 'https://v6.vbb.transport.rest/stops/900013102/departures?direction=9000141

\`\`\`shell
# at U Kottbusser Tor, 10 minutes
curl 'https://v6.vbb.transport.rest/stops/900013102/arrivals?duration=10' -s | jq
curl 'https://v7.vbb.transport.rest/stops/900013102/arrivals?duration=10' -s | jq
\`\`\`
`,
'/stations': `\
### Examples

\`\`\`shell
# autocomplete using vbb-stations-autocomplete
curl 'https://v6.vbb.transport.rest/stations?query=mehringd' -s | jq
curl 'https://v7.vbb.transport.rest/stations?query=mehringd' -s | jq
\`\`\`

\`\`\`js
Expand Down Expand Up @@ -346,7 +346,7 @@ curl 'https://v6.vbb.transport.rest/stations?query=mehringd' -s | jq

\`\`\`shell
# filter vbb-stations
curl 'https://v6.vbb.transport.rest/stations?location.latitude=52.493567' -s | jq
curl 'https://v7.vbb.transport.rest/stations?location.latitude=52.493567' -s | jq
\`\`\`

\`\`\`js
Expand All @@ -365,15 +365,15 @@ curl 'https://v6.vbb.transport.rest/stations?location.latitude=52.493567' -s | j

\`\`\`shell
# filter vbb-stations, get newline-delimited JSON
curl 'https://v6.vbb.transport.rest/stations?location.latitude=52.493567' -H 'accept: application/x-ndjson' -s | jq
curl 'https://v7.vbb.transport.rest/stations?location.latitude=52.493567' -H 'accept: application/x-ndjson' -s | jq
\`\`\`
`,
'/stations/:id': `\
### Example

\`\`\`shell
# lookup U Mehringdamm
curl 'https://v6.vbb.transport.rest/stations/de:11000:900017101' -s | jq
curl 'https://v7.vbb.transport.rest/stations/de:11000:900017101' -s | jq
\`\`\`

\`\`\`js
Expand All @@ -394,56 +394,56 @@ curl 'https://v6.vbb.transport.rest/stations/de:11000:900017101' -s | jq

\`\`\`shell
# stop/station to POI
curl 'https://v6.vbb.transport.rest/journeys?from=900023201&to.id=900980720&to.name=ATZE+Musiktheater&to.latitude=52.54333&to.longitude=13.35167' -s | jq
curl 'https://v7.vbb.transport.rest/journeys?from=900023201&to.id=900980720&to.name=ATZE+Musiktheater&to.latitude=52.54333&to.longitude=13.35167' -s | jq
# without buses, with ticket info
curl 'https://v6.vbb.transport.rest/journeys?from=…&to=…&bus=false&tickets=true' -s | jq
curl 'https://v7.vbb.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.vbb.transport.rest/journeys?from=…&to=…&results=1' -s | jq '.journeys[0]')
journey=$(curl 'https://v7.vbb.transport.rest/journeys?from=…&to=…&results=1' -s | jq '.journeys[0]')
refresh_token=$(echo $journey | jq -r '.refreshToken')

# refresh the journey
curl "https://v6.vbb.transport.rest/journeys/$(echo $refresh_token | url-encode)" -s | jq
curl "https://v7.vbb.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.vbb.transport.rest/journeys?from=…&to=…&results=1' -s | jq '.journeys[0]')
journey=$(curl 'https://v7.vbb.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.vbb.transport.rest/trips/$(echo $trip_id | url-encode)" -s | jq
curl "https://v7.vbb.transport.rest/trips/$(echo $trip_id | url-encode)" -s | jq
\`\`\`
`,
'/radar': `\
### Example

\`\`\`shell
bbox='north=52.52411&west=13.41002&south=52.51942&east=13.41709'
curl "https://v6.vbb.transport.rest/radar?$bbox&results=10" -s | jq
curl "https://v7.vbb.transport.rest/radar?$bbox&results=10" -s | jq
\`\`\`
`,
'/lines': `\
### Example

\`\`\`shell
curl 'https://v6.vbb.transport.rest/lines?operator=796&variants=false' -s | jq
curl 'https://v7.vbb.transport.rest/lines?operator=796&variants=false' -s | jq
\`\`\`
`,
'/lines/:id': `\
### Example

\`\`\`shell
curl 'https://v6.vbb.transport.rest/lines/17442_900' -s | jq
curl 'https://v7.vbb.transport.rest/lines/17442_900' -s | jq
\`\`\`
`,
'/maps/:type': `\
Expand Down
18 changes: 11 additions & 7 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
# Getting Started with `v6.vbb.transport.rest`
# Getting Started with `v7.vbb.transport.rest`

Let's walk through the **requests that are necessary to implement a typical basic transit app**.

*Note:* To properly & securely handle user input containing URL-unsafe characters, always [URL-encode](https://en.wikipedia.org/wiki/Percent-encoding) your query parameters!

The following code snippets use [`curl`](https://curl.haxx.se) (a versatile command line HTTP tool) and [`jq`](https://stedolan.github.io/jq/) (the command line swiss army knife for processing JSON).
The following code snippets use [`curl`](https://curl.haxx.se) (a versatile command line HTTP tool) and [`jq`](https://stedolan.github.io/jq/) (the command line swiss army knife for processing JSON).

> [!NOTE]
> The following `curl` commands use the `-L` flag to follow redirects, because some URLs redirect to similar ones. In your HTTP client, make sure to follow redirects, too.

### 1. search for stops

The `/locations?query=…` route allows you to query stops, points of interest (POIs) & addresses. We're only interested in stops though, so we filter using `poi=false&addresses=false`:

```shell
curl 'https://v6.vbb.transport.rest/locations?poi=false&addresses=false&query=südkreuz' -s | jq
curl 'https://v7.vbb.transport.rest/locations?poi=false&addresses=false&query=südkreuz' -fsSL | jq
```

```js
Expand Down Expand Up @@ -48,7 +51,7 @@ curl 'https://v6.vbb.transport.rest/locations?poi=false&addresses=false&query=s
Let's fetch 5 of the next departures at *Berlin Südkreuz* (which has the ID `900058101`):

```shell
curl 'https://v6.vbb.transport.rest/stops/900058101/departures?results=5' -s | jq
curl 'https://v7.vbb.transport.rest/stops/900058101/departures?results=5' -fsSL | jq
```

```js
Expand Down Expand Up @@ -124,7 +127,7 @@ We call a connection from A to B – at a specific date & time, made up of secti
Let's fetch 2 journeys from `900058101` (*Südkreuz*) to `900110005` (*Senefelderplatz*), departing tomorrow at 2pm (at the time of writing this).

```shell
curl 'https://v6.vbb.transport.rest/journeys?from=900058101&to=900110005&departure=tomorrow+2pm&results=2' -s | jq
curl 'https://v7.vbb.transport.rest/journeys?from=900058101&to=900110005&departure=tomorrow+2pm&results=2' -fsSL | jq
```

```js
Expand Down Expand Up @@ -251,12 +254,13 @@ curl 'https://v6.vbb.transport.rest/journeys?from=900058101&to=900110005&departu
"type": "journey",
"legs": [ /* … */ ],
// …
}]
}],
"realtimeDataUpdatedAt": 1601830200,
}
```

Note that `departure` includes the `departureDelay`, and `arrival` includes the `arrivalDelay`. `plannedDeparture` and `plannedArrival` do not.

### 4. more features

These are the basics. Check the full [API docs](api.md) for all features or use the [OpenAPI playground](https://petstore.swagger.io/?url=https%3A%2F%2Fv6.vbb.transport.rest%2F.well-known%2Fservice-desc%0A) to explore the API!
These are the basics. Check the full [API docs](api.md) for all features or use the [OpenAPI playground](https://petstore.swagger.io/?url=https%3A%2F%2Fv7.vbb.transport.rest%2F.well-known%2Fservice-desc%0A) to explore the API!
6 changes: 3 additions & 3 deletions docs/readme.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# `v6.vbb.transport.rest` documentation
# `v7.vbb.transport.rest` documentation

[`v6.vbb.transport.rest`](https://v6.vbb.transport.rest/) is a [REST API](https://restfulapi.net) for the public transportation system of [Berlin](https://en.wikipedia.org/wiki/Berlin) & [Brandenburg](https://en.wikipedia.org/wiki/Brandenburg), [VBB](https://en.wikipedia.org/wiki/Verkehrsverbund_Berlin-Brandenburg).
[`v7.vbb.transport.rest`](https://v7.vbb.transport.rest/) is a [REST API](https://restfulapi.net) for the public transportation system of [Berlin](https://en.wikipedia.org/wiki/Berlin) & [Brandenburg](https://en.wikipedia.org/wiki/Brandenburg), [VBB](https://en.wikipedia.org/wiki/Verkehrsverbund_Berlin-Brandenburg).

[![API status](https://badgen.net/uptime-robot/status/m793274559-f7e6aec36412170133ab2b04)](https://stats.uptimerobot.com/57wNLs39M/793274559)

Because it wraps [a VBB API](https://github.com/public-transport/hafas-client/blob/6/readme.md#background), it **includes all local traffic, as well as some long-distance trains running in the area**. Essentially, it returns whatever data the [VBB app](https://www.vbb.de/fahrplan/vbb-app) shows, **including realtime delays and disruptions**.

- [Getting Started](getting-started.md)
- [API documentation](api.md)
- [OpenAPI playground](https://petstore.swagger.io/?url=https%3A%2F%2Fv6.vbb.transport.rest%2F.well-known%2Fservice-desc%0A)
- [OpenAPI playground](https://petstore.swagger.io/?url=https%3A%2F%2Fv7.vbb.transport.rest%2F.well-known%2Fservice-desc%0A)

## Why use this API?

Expand Down
2 changes: 1 addition & 1 deletion license.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2022, Jannis R
Copyright (c) 2024, Jannis R

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

Expand Down
Loading
Loading