{"id":13847116,"url":"https://github.com/delvedor/fastify-example","last_synced_at":"2025-04-04T07:06:33.184Z","repository":{"id":41472304,"uuid":"325050078","full_name":"delvedor/fastify-example","owner":"delvedor","description":"This project is a small but feature complete application build with Fastify and Svelte, and it aims to show all the core concepts of Fastify, best practices, and recommendations.","archived":false,"fork":false,"pushed_at":"2023-02-05T20:10:26.000Z","size":415,"stargazers_count":741,"open_issues_count":8,"forks_count":106,"subscribers_count":17,"default_branch":"main","last_synced_at":"2025-03-28T06:06:56.447Z","etag":null,"topics":["example","fastify","nodejs"],"latest_commit_sha":null,"homepage":"https://fastify.io","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/delvedor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-12-28T15:39:49.000Z","updated_at":"2025-03-26T06:50:56.000Z","dependencies_parsed_at":"2024-01-15T20:47:33.706Z","dependency_job_id":"abb6910f-b9bb-4ec9-aae6-1a17a882b313","html_url":"https://github.com/delvedor/fastify-example","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/delvedor%2Ffastify-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delvedor%2Ffastify-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delvedor%2Ffastify-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delvedor%2Ffastify-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/delvedor","download_url":"https://codeload.github.com/delvedor/fastify-example/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247135144,"owners_count":20889421,"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":["example","fastify","nodejs"],"created_at":"2024-08-04T18:00:54.642Z","updated_at":"2025-04-04T07:06:33.159Z","avatar_url":"https://github.com/delvedor.png","language":"JavaScript","readme":"# Fastify App Example\n\nThis project is a small but feature complete application build with Fastify and Svelte,\nand it aims to show all the core concepts of Fastify, best practices, and recommendations.\n\nThere is no attached blog post or tutorial, you should go through the application code\nand read the code comments, which will explain you best practices, protips, suggestions\nand so forth, I hope you will like it!\n\n## What is this application doing?\n\nThis application is an URL shortener, it exposes an admin UI and a series of routes\nunder the `/_app` prefix.\nAny other request will be interpreted as redirect. If a redirect does not exists, \nthe user will either see a standard 404 page, or a page with a series of suggestions\ngenerated by Elasticsearch *(both this pages are server side rendered!)*.\n\nThe admin logins via GitHub OAuth, the application is also protected by a rate limiter\nand during development it exposes a Swagger UI with every endpoint.\nRead the next section to understand how the project works and how it is recommended\nto explore it.\n\n## Project structure\n\nThe project follows a well established pattern within the Fastify community,\nit has two top level folders, `plugins` and `routes`.\n\n\u003cp style=\"text-align:center\"\u003e\n  \u003cimg src=\"./structure.png\" alt=\"project structure\"\u003e\n\u003c/p\u003e\n\nThe first one contains all the code that should be shared across your entire\naplication, such as authentication and rate limiting, while the second one\ncontains all the business logic, such as the redirect code and the admin APIs.\n\nWe recommend to follow this pattern, you can generate a project with the same\nstructure by using [fastify-cli](https://github.com/fastify/fastify-cli).\n\n### How should I read through the comments?\n\nYou can read the project in any order, but I would recommend the following:\n\n1. `app.js`\n1. `plugins/authorization.js`\n1. `plugins/elasticsearch.js`\n1. `plugins/rate-limit.js`\n1. `plugins/validUrl.js`\n1. `plugins/swagger.js`\n1. `routes/status.js`\n1. `routes/frontend.js`\n1. `routes/admin.js`\n1. `routes/redirect/index.js`\n1. `routes/redirect/update-count.js`\n1. `routes/redirect/worker.cjs`\n1. `routes/redirect/App.svelte`\n1. `ui/*`\n1. `test/helper.js`\n1. `test/plugins/validUrl.test.js`\n1. `test/routes/status.test.js`\n1. `test/routes/admin.test.js.test.js`\n1. `test/routes/redirect.test.js.test.js`\n\n## FAQ \n\n### You are using ESM, how are you compiling the project?\n\nI'm not. From Node.js v12.20 and Node.js v14 ES Modules are supported [out of the box](https://nodejs.org/api/esm.html).\nAs you can see in the `package.json`, there is a new field: `{ \"type\": \"module\" }`.\nThat field will instruct Node.js that the project is using ESM instead of CJS (common js, which is\n`require`/`module.exports`), and every `.js` file will be a ESM module, while every `.cjs` file will be a CJS module.\n\nA follow up question you can ask now is: \"why is there a `rollup.config.js`?\nGreat question! That is used for compiling the Svelte frontend locatated in `ui/`.\n\n### Can I use TypeScript?\n\nYes! Fastify supports TypeScript [out of the box](https://www.fastify.io/docs/latest/TypeScript/)!\nThe project is written in plain JavaScript because I didn't want to add too many things\nto the project, but probably in the future there will be a branch with a TypeScript implementation.\n\n### Why aren't you using a try-catch block in route declarations?\n\nFastify supports promises/async-await [out of the box](https://www.fastify.io/docs/latest/Routes/#async-await).\nEverything is handled for you, if you throw an error inside a route handler (same goes\nfor hooks or plugins) the error will be caught automatically by Fastify and return\nthe most approriate error.\n\n### Why Svelte?\n\nNo specific reason, any frontend framework will do the job well. I used Svelte because I like\nit and because it makes it very easy to think about the frontend, without making me think\ntoo much about how something should be written or weird APIs, but directly focusing\non the business logic while writing almost plain html/css/js.\n\n## How to run this project\n\n1. Create an `.env` file from the template:\n\n    ```sh\n    cp .env.template .env\n    ```\n\n2. Create a new GitHub OAuth application [here](https://github.com/settings/applications/new), then copy the app id and secret and add them to the env file:\n\n    ```dosini\n    GITHUB_APP_ID=\u003capp-id\u003e\n    GITHUB_APP_SECRET=\u003capp-secret\u003e\n    ```\n\n3. Add your primary GitHub email to the `ALLOWED_USERS` variable:\n\n    ```dosini\n    ALLOWED_USERS=\u003cyour-primary-github-mail\u003e\n    ```\n\n4. Run the `keys-generator` script and store the result in the `COOKIE_SECRET` env variable:\n\n    ```sh\n    node scripts/keys-generator.js\n    ```\n\n    ```dosini\n    COOKIE_SECRET=\u003cgenerated-key\u003e\n    ```\n\nNow you can either run the project locally or deploy it.\n\n### Locally\n\n1. Use Node.js v18.\n\n    ```sh\n    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash\n    nvm install 18\n    node -v # should be v18.minor.patch\n    ```\n\n2. Install the project dependencies:\n\n    ```sh\n    npm install\n    ```\n\n3. In a separate terminal window, run Elasticsearch:\n\n    ```sh\n    npm run elasticsearch\n    ```\n\n4. Once Elasticsearch is up and running, run the `prepare-elasticsearch` script and copy the result in the `ELASTIC_URL` and `ELASTIC_API_KEY` env variables:\n\n    ```js\n    node scripts/prepare-elasticsearch.js\n    ```\n\n    ```dosini\n    ELASTIC_ADDRESS=\u003cresult.address\u003e\n    ELASTIC_API_KEY=\u003cresult.apiKey\u003e\n    ```\n\n5. You are all set! Run the project with thw following command:\n\n    ```sh\n    npm run dev\n    ```\n\n### Deploy\n\nThis section contains instructions for deploying this application.\n\nWould you like to see more recipes? Open an [issue](https://github.com/delvedor/fastify-example/issues/new).\nDo you already have a deploy recipe and want to share it? That's awesome, send a [pull request](https://github.com/delvedor/fastify-example/compare)!\n\n#### Cloud  Run\n\nOpen [`deploy-recipes/cloud-run`](./deploy-recipes/cloud-run), you will find everything you need there.\n\n#### Elastic Cloud\n\nYou can create an Elasticsearch cluster with Elastic Cloud, with a free 14-day trial of the [Elasticsearch Service](https://www.elastic.co/elasticsearch/service).\n\n## Contribute\n\nFeel free to send pull request with new features, bugfix or documentation improvements!\n\n## Questions\n\nOpen an [issue](https://github.com/delvedor/fastify-example/issues/new) or take a look at our [`fastify/help`](https://github.com/fastify/help) repository.\nWe also have a [Discord community](https://discord.gg/D3FZYPy) you can join.\n\nIf you have any question related to Elasticsearch or the Elasticsearch client,\nyou can open a new discussion on [discuss.elastic.co](https://discuss.elastic.co/)\nor in the client [issue tracker](https://github.com/elastic/elasticsearch-js/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).\n\n## License\n\nThis software is licensed under the [Apache 2 license](./LICENSE).\n","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdelvedor%2Ffastify-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdelvedor%2Ffastify-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdelvedor%2Ffastify-example/lists"}