{"id":15640239,"url":"https://github.com/davideast/hnpwa-api","last_synced_at":"2025-04-15T11:53:37.972Z","repository":{"id":23175536,"uuid":"92880667","full_name":"davideast/hnpwa-api","owner":"davideast","description":"CDN cached Hacker News API","archived":false,"fork":false,"pushed_at":"2022-12-10T20:29:07.000Z","size":1047,"stargazers_count":82,"open_issues_count":25,"forks_count":2,"subscribers_count":6,"default_branch":"main","last_synced_at":"2024-10-29T13:07:19.915Z","etag":null,"topics":["cloud-functions","firebase","hacker-news"],"latest_commit_sha":null,"homepage":"https://api.hnpwa.com/v0/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/davideast.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-30T22:12:31.000Z","updated_at":"2024-10-27T05:07:21.000Z","dependencies_parsed_at":"2022-07-25T09:47:09.023Z","dependency_job_id":null,"html_url":"https://github.com/davideast/hnpwa-api","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davideast%2Fhnpwa-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davideast%2Fhnpwa-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davideast%2Fhnpwa-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davideast%2Fhnpwa-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/davideast","download_url":"https://codeload.github.com/davideast/hnpwa-api/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249067759,"owners_count":21207395,"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":["cloud-functions","firebase","hacker-news"],"created_at":"2024-10-03T11:32:33.934Z","updated_at":"2025-04-15T11:53:37.947Z","avatar_url":"https://github.com/davideast.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# HNPWA API\n\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"600\" height=\"300\" src=\"https://raw.githubusercontent.com/davideast/hnpwa-api/master/assets/rocket-orange.png\"\u003e\n\u003c/a\u003e\n\nDeploy a CDN cached Hacker News API to your own Firebase Hosting Domain. All in two lines of code 😎\n\n**Heavily** inspired/guided by [cheeaun's](https://github.com/cheeaun) [node-hnapi](https://github.com/cheeaun/node-hnapi).\n\n## Install\n```bash\nnpm i hnpwa-api\n```\n\n## Basic usage\nImport and use in your `functions/index.js` file:\n```js\nconst hnapi = require('hnpwa-api');\nexports.api = hnapi.trigger({\n   useCors: false, // defaults to false\n   useCompression: true, // defaults to true\n   browserCacheExpiry: 300, // in seconds (5 min is the default)\n   cdnCacheExpiry: 600, // in seconds (10 min is the default)\n   staleWhileRevalidate: 120, // Allow CDN to serve stale data 120 seconds after cdnCacheExpiry\n   firebaseAppName: 'hnpwa-api', // defaults to hnpwa-api\n   offline: false, // Serves offline data if data is downloaded (See Global Module guide)\n   routerPath: 'api', // provide a serving path ex: mysite.com/api/news.json\n});\n```\n\n## Why?\nTwo reasons: **latency** and **same domain**.\n\n### Latency\nThis API is designed for Firebase Hosting which is backed by a global CDN. Responses are cached in edges around the globe which results in low latency.\n\n[Latency test: CDN cached vs. in memory cache](https://latency.apex.sh/?url=https%3A%2F%2Fhnpwa-api.firebaseapp.com%2Fnews.json%3Fpage%3D1\u0026compare=https%3A%2F%2Fnode-hnapi.herokuapp.com%2Fnews%3Fpage%3D1)\n\n### Same domain\nWith HTTP/2 you reuse one connection per domain. This package allows you to easily deploy your own HNAPI on your own domain for one nice TCP connection.\n\n## Setup Tutorial\n\n#### 1. Install the Firebase CLI: \n```bash\nnpm i -g firebase-tools\n```\n\n#### 2. Initialize Cloud Functions for Firebase\n```bash\nfirebase init functions\n```\n\n#### 3. Install hnpwa-api\nInside of the `functions` folder, install `hnpwa-api`:\n```bash\ncd functions\nnpm i hnpwa-api --save # not needed on npm 5 but you get what im sayin\n```\n\n#### 4. Add HNAPI endpoint\nOpen `functions/index.js`, and configure your HNAPI.\n\n```js\nconst hnapi = require('hnpwa-api');\nexports.api = hnapi.trigger({\n   useCors: false, // defaults to false\n   useCompression: true, // defaults to true\n   browserCacheExpiry: 300, // in seconds (5 min is the default)\n   cdnCacheExpiry: 600, // in seconds (10 min is the default)\n   staleWhileRevalidate: 120, // Allow CDN to serve stale data 120 seconds after cdnCacheExpiry\n   firebaseAppName: 'hnpwa-api', // defaults to hnpwa-api\n   offline: false, // Serves offline data if data is downloaded (See Global Module guide)\n   routerPath: 'api', // provide a serving path ex: mysite.com/api/news.json\n});\n```\n\n#### 5. Initialize Firebase Hosting\n```bash\nfirebase init hosting\n```\n\n#### 6. Create a redirect for the API function\nOpen `firebase.json` and create a redirect to call out to the HNAPI:\n```json\n{\n  \"hosting\": {\n    \"public\": \"public\",\n    \"rewrites\": [{\n       \"source\": \"**\",\n       \"function\": \"api\"\n    }]\n  }\n}\n```\n\n#### 7. Deploy!\n```bash\nfirebase deploy\n```\n\nThat's all there is to it. Feel free to file an issue if you find a bug.\n\n## Global Module use\nThe hnpwa-api module can either be downloaded as a global module or used from the \n`node_modules/.bin/hnpwa-api` directory.\n\n### Serving offline\nThe global module provides the ability to save data locally for offline serving. If \nyou're developing on a bus, airplane, or someother place without a connection you'll\nneed this. \n\n```bash\n# 1) Save to node_modules/hnpwa-api/offline (~10mb)\nnode_modules/.bin/hnpwa-api --save\n# 2) Now serve offline\nnode_modules/.bin/hnpwa-api --serve --offline\n```\n\n## Non-Firebase setup\nNot using Cloud Functions or Firebase Hosting as your backend? No problem. This library still has you covered.\n\n```js\nconst hnapi = require('hnpwa-api');\n// does not include any middleware like the trigger() call above\nconst expressApp = hnapi.app(); // optionally provide a firebase app name\nexpressApp.listen(3000, () =\u003e console.log('Listening all on my own!'));\n```\n\nThis returns an express app instance with the expected HN API endpoints. No middleware is attached unlike the `trigger(config)` method. \n\n### Why do I need a Firebase App Name if I'm not using Firebase Hosting?\nYou may not use Firebase as your backend, but Hacker News does. The base HN API is backed by the Firebase Database. This library uses the Firebase Node SDK to retrieve data and coalesce it into a single UI friendly response.\n\n### Contribute!?\n```bash\ngit clone https://github.com/davideast/hnpwa-api/\nnpm i\nnpm run build # single build of the project\nnpm run watch # typescript (tsc) watcher\nnpm run serve # local node debug server\nnpm run pack # local tarball for test installations\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavideast%2Fhnpwa-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavideast%2Fhnpwa-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavideast%2Fhnpwa-api/lists"}