{"id":13623534,"url":"https://github.com/public-transport/hafas-client","last_synced_at":"2025-04-07T01:12:45.953Z","repository":{"id":38451562,"uuid":"61675896","full_name":"public-transport/hafas-client","owner":"public-transport","description":"JavaScript client for HAFAS public transport APIs.","archived":false,"fork":false,"pushed_at":"2024-09-25T22:43:29.000Z","size":23617,"stargazers_count":274,"open_issues_count":58,"forks_count":53,"subscribers_count":14,"default_branch":"main","last_synced_at":"2024-10-29T21:03:29.733Z","etag":null,"topics":["api","db","hafas","hafas-client","public-transport","transit","transport","vbb"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/public-transport.png","metadata":{"files":{"readme":"docs/readme.md","changelog":null,"contributing":"contributing.md","funding":".github/funding.yml","license":"license.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"liberapay":"derhuerst","patreon":"derhuerst","github":"derhuerst"}},"created_at":"2016-06-22T00:14:13.000Z","updated_at":"2024-10-28T00:15:22.000Z","dependencies_parsed_at":"2023-11-11T07:06:54.239Z","dependency_job_id":"8220bd06-3a92-40b8-b680-d42b931e77ab","html_url":"https://github.com/public-transport/hafas-client","commit_stats":{"total_commits":1261,"total_committers":33,"mean_commits":38.21212121212121,"dds":0.09357652656621729,"last_synced_commit":"e9211e8105049b39c00c62fb33c55990ec3e45e7"},"previous_names":[],"tags_count":169,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/public-transport%2Fhafas-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/public-transport%2Fhafas-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/public-transport%2Fhafas-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/public-transport%2Fhafas-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/public-transport","download_url":"https://codeload.github.com/public-transport/hafas-client/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247574089,"owners_count":20960496,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","db","hafas","hafas-client","public-transport","transit","transport","vbb"],"created_at":"2024-08-01T21:01:32.870Z","updated_at":"2025-04-07T01:12:45.929Z","avatar_url":"https://github.com/public-transport.png","language":"JavaScript","funding_links":["https://liberapay.com/derhuerst","https://patreon.com/derhuerst","https://github.com/sponsors/derhuerst"],"categories":["JavaScript"],"sub_categories":[],"readme":"# `hafas-client` documentation\n\n**[API documentation](api.md)**\n\n## Migrating from an old `hafas-client` version\n\n- [`4` → `5` migration guide](migrating-to-5.md)\n\n## Throttling requests\n\nThere's opt-in support for throttling requests to the endpoint.\n\n```js\nimport {createClient} from 'hafas-client'\nimport {withThrottling} from 'hafas-client/throttle.js'\nimport {profile as dbProfile} from 'hafas-client/p/db/index.js'\n\nconst userAgent = 'link-to-your-project-or-email' // adapt this to your project!\n\n// create a throttled HAFAS client with Deutsche Bahn profile\nconst client = createClient(withThrottling(dbProfile), userAgent)\n\n// Berlin Jungfernheide to München Hbf\nawait client.journeys('8011167', '8000261', {results: 1})\n```\n\nYou can also pass custom values for the nr of requests (`limit`) per interval into `withThrottling`:\n\n```js\n// 2 requests per second\nconst throttledDbProfile = withThrottling(dbProfile, 2, 1000)\nconst client = createClient(throttledDbProfile, userAgent)\n```\n\n## Retrying failed requests\n\nThere's opt-in support for retrying failed requests to the endpoint.\n\n```js\nimport {createClient} from 'hafas-client'\nimport {withRetrying} from 'hafas-client/retry.js'\nimport {profile as dbProfile} from 'hafas-client/p/db/index.js'\n\nconst userAgent = 'link-to-your-project-or-email' // adapt this to your project!\n\n// create a client with Deutsche Bahn profile that will retry on HAFAS errors\nconst client = createClient(withRetrying(dbProfile), userAgent)\n```\n\nYou can pass custom options into `withRetrying`. They will be passed into [`retry`](https://github.com/tim-kos/node-retry#tutorial).\n\n```js\n// retry 2 times, after 10 seconds \u0026 30 seconds\nconst retryingDbProfile = withRetrying(dbProfile, {\n\tretries: 2,\n\tminTimeout: 10 * 1000,\n\tfactor: 3\n})\nconst client = createClient(retryingDbProfile, userAgent)\n```\n\n## User agent randomization\n\nBy default, `hafas-client` randomizes the client name that you pass into `createClient`, and sends it as [`User-Agent`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent) in a randomized form:\n\n```js\nimport {createClient} from 'hafas-client'\n// …\n\nconst userAgent = 'my-awesome-program'\nconst client = createClient(someProfile, userAgent)\n\nawait client.journeys(/* … */)\n// User-Agent: my-awee70429some-pre70429ogram\nawait client.journeys(/* … */)\n// User-Agent: my-awesom9bb8e2e-prog9bb8e2ram\n```\n\nYou can turn this off by setting `profile.randomizeUserAgent` to `false`:\n\n```js\nconst client = createClient({\n\t...someProfile,\n\trandomizeUserAgent: false,\n}, userAgent)\n```\n\n## Logging requests\n\nYou can use `profile.logRequest` and `profile.logResponse` to process the raw [Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response), respectively.\n\nAs an example, we can implement a custom logger:\n\n```js\nimport {createClient} from 'hafas-client'\nimport {profile as dbProfile} from 'hafas-client/p/db/index.js'\n\nconst userAgent = 'link-to-your-project-or-email' // adapt this to your project!\n\nconst logRequest = (ctx, fetchRequest, requestId) =\u003e {\n\t// ctx looks just like with the other profile.* hooks:\n\tconst {dbProfile, opt} = ctx\n\n\tconsole.debug(requestId, fetchRequest.headers, fetchRequest.body + '')\n}\n\nconst logResponse = (ctx, fetchResponse, body, requestId) =\u003e {\n\tconsole.debug(requestId, fetchResponse.headers, body + '')\n}\n\n// create a client with Deutsche Bahn profile that debug-logs\nconst client = createClient({\n\t...dbProfile,\n\tlogRequest,\n\tlogResponse,\n}, userAgent)\n```\n\n```js\n// logRequest output:\n'29d0e3' {\n\taccept: 'application/json',\n\t'accept-encoding': 'gzip, br, deflate',\n\t'content-type': 'application/json',\n\tconnection: 'keep-alive',\n\t'user-agent': 'hafas842c51-clie842c51nt debug C842c51LI'\n} {\"lang\":\"de\",\"svcReqL\":[{\"cfg\":{\"polyEnc\":\"GPA\"},\"meth\":\"LocMatch\",…\n// logResponse output:\n'29d0e3' {\n\t'content-encoding': 'gzip',\n\t'content-length': '1010',\n\t'content-type': 'application/json; charset=utf-8',\n\tdate: 'Thu, 06 Oct 2022 12:31:09 GMT',\n\tserver: 'Apache',\n\tvary: 'User-Agent'\n} {\"ver\":\"1.45\",\"lang\":\"deu\",\"id\":\"sb42zgck4mxtxm4s\",\"err\":\"OK\",\"graph\"…\n```\n\nThe default `profile.logRequest` [`console.error`](https://nodejs.org/docs/latest-v10.x/api/console.html#console_console_error_data_args)s the request body, if you have set `$DEBUG` to `hafas-client`. Likewise, `profile.logResponse` `console.error`s the response body.\n\n## Error handling\n\nUnexpected errors – e.g. due to bugs in `hafas-client` itself – aside, its methods may reject with the following errors:\n\n- `HafasError` – A generic error to signal that something HAFAS-related went wrong, either in the client, or in the HAFAS endpoint.\n- `HafasAccessDeniedError` – The HAFAS endpoint has rejected your request because you're not allowed to access it (or the specific API call). Subclass of `HafasError`.\n- `HafasInvalidRequestError` – The HAFAS endpoint reports that an invalid request has been sent. Subclass of `HafasError`.\n- `HafasNotFoundError` – The HAFAS endpoint does not know about such stop/trip/etc. Subclass of `HafasError`.\n- `HafasServerError` – An error occured within the HAFAS endpoint, so that it can't fulfill the request; For example, this happens when HAFAS' internal backend is unavailable. Subclass of `HafasError`.\n\nEach error has the following properties:\n\n- `isHafasError` – Always `true`. Allows you to differente HAFAS-related errors from e.g. network errors.\n- `code` – A string representing the error type for all other error classes, e.g. `INVALID_REQUEST` for `HafasInvalidRequestError`. `null` for plain `HafasError`s.\n- `isCausedByServer` – Boolean, telling you if the HAFAS endpoint says that it couldn't process your request because *it* is unavailable/broken.\n- `hafasCode` – A HAFAS-specific error code, if the HAFAS endpoint returned one; e.g. `H890` when no journeys could be found. `null` otherwise.\n- `request` – The [Fetch API `Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) of the request.\n- `url` – The URL of the request.\n- `response` – The [Fetch API `Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response).\n\nTo check **if an error from `hafas-client` is HAFAS-specific, use `error instanceof HafasError`**:\n\n```js\nimport {HafasError} from 'hafas-client/lib/errors.js'\n\ntry {\n\tawait client.journeys(/* … */)\n} catch (err) {\n\tif (err instanceof HafasError) {\n\t\t// HAFAS-specific error\n\t} else {\n\t\t// different error, e.g. network (ETIMEDOUT, ENETDOWN)\n\t}\n}\n```\n\nTo determine **if you should automatically retry an error, use `!error.causedByServer`**.\n\n## Using `hafas-client` from another language\n\nIf you want to use `hafas-client` to access HAFAS APIs but work with non-Node.js environments, you can use [`hafas-client-rpc`](https://github.com/derhuerst/hafas-client-rpc) to create a [JSON-RPC](https://www.jsonrpc.org) interface that you can send commands to.\n\n## Writing a profile\n\nCheck [the guide](writing-a-profile.md).\n\n## General documentation for `mgate.exe` APIs\n\n[`hafas-mgate-api.md`](hafas-mgate-api.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpublic-transport%2Fhafas-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpublic-transport%2Fhafas-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpublic-transport%2Fhafas-client/lists"}