/ README.md
README.md
  1  <!-- PROJECT SHIELDS -->
  2  
  3  [![Codacy Badge][codacy-shield]][codacy-url]
  4  [![Issues][issues-shield]][issues-url]
  5  [![Forks][forks-shield]][forks-url]
  6  [![Stargazers][stars-shield]][stars-url]
  7  [![repo-size][repo-size-shield]][repo-size-url]
  8  [![Contributors][contributors-shield]][contributors-url]
  9  [![license][license-shield]][license-url]
 10  
 11  <!-- PROJECT LOGO -->
 12  <br />
 13  <div align="center">
 14  
 15    <h3 align="center">Creature API Boilerplate</h3>
 16  
 17     <a href="https://api-boilerplate.applycreatures.com/">
 18        <img src="public/apply-creatures-logo.png" alt="screenshot" width="30%">
 19     </a>
 20  
 21    <p align="center">
 22      Boilerplate for REST API components
 23      <br />
 24      <a href="https://api-boilerplate.applycreatures.com/"><strong>See live (soon) ยป</strong></a>
 25      <br />
 26      <br />
 27      <a href="https://github.com/apply-creatures/creature-api-boilerplate/issues">Report Bug</a>
 28      ::
 29      <a href="https://github.com/apply-creatures/creature-api-boilerplate/issues">Request Feature</a>
 30    </p>
 31  </div>
 32  
 33  <p align="center">
 34  OK, DOkey
 35  </p>
 36  
 37  <!-- TABLE OF CONTENTS -->
 38  <details>
 39    <summary>Table of Contents</summary>
 40        <ol>
 41           <li>
 42              <a href="#about">About</a>
 43              <ul>
 44                  <li>
 45                      <a href="#built-with">Built With</a>
 46                  </li>
 47              </ul>
 48           </li>
 49           <li>
 50           <a href="#getting-started">Getting Started</a>
 51           <ul>
 52              <li><a href="#prerequisites">Prerequisites</a></li>
 53              <li><a href="#repo">Repo</a></li>
 54              <li><a href="#develop">Develop</a></li>
 55              <li><a href="#build">Build</a></li>
 56              <li><a href="#deploy">deploy</a></li>
 57           </ul>
 58           </li>
 59           <li><a href="#roadmap">Roadmap</a></li>
 60           <li><a href="#contributing">Contributing</a></li>
 61           <li><a href="#license">License</a></li>
 62           <li><a href="#acknowledgments">Acknowledgments</a></li>
 63        </ol>
 64  </details>
 65  
 66  <hr/>
 67  
 68  **TL;DR** - skip to [getting-started](#getting-started)
 69  
 70  
 71  <hr/>
 72  
 73  <!-- ABOUT THE PROJECT -->
 74  
 75  ## About
 76  
 77  Setting up an API server is a daunting exercise with authorization, doc generated from source, helmets and other safe props.
 78  So I created a template, that way one can kick things off almost right away.
 79  
 80  <div align="center">
 81     <a href="#">
 82        <img src="public/apply-creatures-logo.png" alt="screenshot" width="60%">
 83     </a>
 84  </div>
 85  
 86  ## Features
 87  
 88  * REST APIs
 89  * Authentication
 90  * OpenAPI Doc generation and Swagger UI
 91  * RedDoc generation from API specs
 92  * Postgres integration
 93  * (some) unit tests
 94  
 95  Of course, nothing is perfect, but I will try to keep this up to date and fix issues right here. If I failed in accomplishing that, shoot me a message.
 96  If you've truly tried everything and still can't get this to work for you, try to reach out. Or raise an issue. But I make no promise
 97  
 98  <p align="right">(<a href="#readme-top">back to top</a>)</p>
 99  
100  ### Built With
101  
102  - [node.js](https://nodejs.org/) - of course
103  - [feathersjs](https://feathersjs.com/) - never did before, I almost used another one, but it seems solid
104  - [sequelize](https://sequelize.org/) - because it simplifies interfacing with a DB, and abstracts which kind of DB that is
105  - [winston](https://github.com/winstonjs/winston) - for better logging
106  
107  ### Also using
108  
109  - [OpenAPI](https://www.openapis.org/) - To nicely document the API interfaces
110  - [Redoc](https://github.com/Redocly/redoc) - Because it reads more like real documentation  
111  - [biome](https://biomejs.dev/linter/) - that keeps my code well formatted
112  
113  <hr/>
114  
115  <!-- GETTING STARTED -->
116  
117  ## Getting Started
118  
119  ### Prerequisites
120  
121  - you need [Git](https://git-scm.com/) installed
122  - and [nodejs](https://nodejs.org/) of course
123  - [postgres](https://www.postgresql.org/) installed
124  
125  ### Set up repo
126  
127  ```bash
128  $ git clone https://github.com/apply-creatures/creature-api-boilerplate.git
129  ```
130  
131  Navigate to the repo root's folder & install dependencies
132  
133  ```bash
134  $ cd ./creature-api-boilerplate && npm install
135  ```
136  
137  ### Develop
138  
139  **Start postgres**
140  
141  you may also want to create the database or the server may crash at startup 
142  
143  ```sh
144  psql -U postgres -h localhost
145  CREATE DATABASE creature_api_boilerplate;
146  ```
147  
148  **Launch in develop mode**
149  
150  ```bash
151  $ npm run develop # code changes will automatically reload the server
152  ```
153  
154  **Access via browser**
155  
156  - Hit [http://localhost:3030](http://localhost:3030)
157  
158  ### Build
159  
160  This command will compile for production deployment:
161  
162  ```bash
163  $ npm run compile
164  ```
165  
166  It generates the files as js for node to execute directly, yeah Nodejs doesn't understand Typescript.
167  
168  Then you can:
169  
170  ```sh
171  npm run start:prod
172  ```
173  
174  But if you are truely in production as this point you may need to check the Docker container [file](./Dockerfile) and the compose [here](./docker-compose.yml) which would spin up a postgres and the server. 
175  
176  ### Deploy
177  
178  #### First time deploy
179  
180  To stand up the server and db, use a containers.
181  
182  1. Launch the app
183  
184  ```bash
185  fly launch
186  ```
187  
188  Make sure to use the appropriate port in the config, and that it creates a postgres machine too.
189  
190  then
191  
192  2. Create the DB (optional)
193  
194  It may be required, for some reason the db does not create, if that is the case, do it yourself. 
195  Once the db machine is created, look at the fly doc to connect to it via their cli. Then create the DB.
196  
197  3. Set env secrets:
198  
199  ```bash
200  fly secrets set POSTGRES_PASSWORD=thepassword # password is shown during db machine creation
201  fly secrets set POSTGRES_HOST=host.internal # e.g creature-api-boilerplate-db.internal
202  ```
203  
204  It will restart the app and thing should be all set, if not...
205  
206  4. Check logs
207  
208  Go check the monitoring page, the live logs would show you if the app failed for whatever reason to start properly.
209  
210  _here is how  a clean start looks like:_
211  
212  ```bash
213  2024-06-18T12:21:19.673 runner[148e2592a77e18] waw [info] Machine started in 441ms
214  2024-06-18T12:21:19.674 proxy[148e2592a77e18] waw [info] machine started in 444.309174ms
215  2024-06-18T12:21:20.312 app[148e2592a77e18] waw [info] > creature-api-boilerplate@0.3.0 start:prod
216  2024-06-18T12:21:20.312 app[148e2592a77e18] waw [info] > node lib/
217  2024-06-18T12:21:21.651 app[148e2592a77e18] waw [info] [2024-06-18T12:21:21.650Z] [info] []: configuring local and jwt strategies
218  2024-06-18T12:21:21.715 app[148e2592a77e18] waw [info] [2024-06-18T12:21:21.715Z] [info] []: About to check authenticate...
219  2024-06-18T12:21:21.716 app[148e2592a77e18] waw [info] [2024-06-18T12:21:21.716Z] [info] []: Setting sequelizeClient...
220  2024-06-18T12:21:21.725 app[148e2592a77e18] waw [info] [2024-06-18T12:21:21.725Z] [info] []: Masters service is hooked
221  2024-06-18T12:21:21.727 app[148e2592a77e18] waw [info] [2024-06-18T12:21:21.727Z] [info] []: Upload service is hooked
222  2024-06-18T12:21:21.729 app[148e2592a77e18] waw [info] [2024-06-18T12:21:21.729Z] [info] []: User service is hooked
223  2024-06-18T12:21:21.729 app[148e2592a77e18] waw [info] [2024-06-18T12:21:21.729Z] [info] []: setting hooks...
224  2024-06-18T12:21:21.733 app[148e2592a77e18] waw [info] [2024-06-18T12:21:21.733Z] [info] []: About to sync DB...
225  2024-06-18T12:21:21.734 app[148e2592a77e18] waw [info] [2024-06-18T12:21:21.734Z] [info] []: Once task is ready...
226  2024-06-18T12:21:21.747 app[148e2592a77e18] waw [info] [2024-06-18T12:21:21.747Z] [info] []: Feathers application started on http://localhost:3030
227  2024-06-18T12:21:21.793 app[148e2592a77e18] waw [info] [2024-06-18T12:21:21.792Z] [info] []: Connection has been established successfully.
228  2024-06-18T12:21:21.871 app[148e2592a77e18] waw [info] [2024-06-18T12:21:21.871Z] [info] []: Database synchronized successfully.
229  2024-06-18T12:21:22.145 proxy[148e2592a77e18] waw [info] machine became reachable in 2.471743984s
230  ```
231  
232  5. Hit the app via browser
233  
234  Navigate to the app public hostname, it should show some page.
235  
236  #### subsequent deploments
237  
238  1. Run:
239  
240  ```bash
241  $ fly deploy
242  ```
243  
244  that's it.
245  
246  2. Check logs
247  
248  Go check the monitoring page, the live logs, in case you've broken it.
249  
250  <p align="right">(<a href="#readme-top">back to top</a>)</p>
251  
252  ### Adding an endpoint
253  
254  An endpoint is a service.
255  
256  - Look at an exiting hook in the [services](./src/services/) folder 
257  - Create your own service, or add a function to an existing one
258  - Make sure to document your endpoint via swagger annotation
259  - Verify it works and that the doc and schema's alright
260  
261  ### Adding a model
262  
263  You may want to store stuff in a DB. for that create a model for your entities.
264  If you spread direct connections in your service, it will be hard to keep things DRY. And, you may seriously sabotage potential desires to switch to another type of DB down the road. And you will ending writing more code than you need to. Instead:
265  
266  - Look at an existing model in the [models](./src/models/) folder
267  - Figure it out
268  
269  <hr/>
270  
271  ## Roadmap
272  
273  - [x] Setup a repo with an API framework -> feathersjs
274  - [x] Setup all the whistle, helmet with headers, CORS, serving static welcome page, logger
275  - [x] Add a bit of midlayer, some endpoint with some models
276  - [x] Sequelize to hook this up to a DB (mostly for auth)
277  - [x] Setup auth, username/password and JWT, dahell with social
278  = [x] Swagger - I think that's done, maybe more spec propoerties but that's enough
279  - [x] Fix auth - creating users with encrypted password works, but for some reason logging in with password does not work
280  - [x] ReDoc from swagger spec
281  - [x] Serve some static landing page with links to docs
282  - [x] Some env variable for DB settings
283  - [ ] More testing
284  - [ ] More I guess
285  
286  <hr/>
287  
288  ## Contributing
289  
290  Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
291  
292  If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement".
293  Don't forget to give the project a star! Thanks again!
294  
295  1. fork the Project
296  2. create your Feature Branch (`git checkout -b feature/some-feature`)
297  3. commit your Changes (`git commit -m 'Add some feature'`)
298  4. push to the Branch (`git push origin feature/some-feature`)
299  5. open a Pull Request
300  
301  <hr/>
302  
303  <p align="right">(<a href="#readme-top">back to top</a>)</p>
304  
305  <hr/>
306  
307  ## Acknowledgments
308  
309  It would never end. I've done this work not just off dozens of other people's open source work, but hundreds thousands or maybe millions.
310  Special kudo to the gatsby team that made such an easy tool to build static websites, the pipeline and community is awesome.
311  
312  Whoever made markdown, although that was probably inspired by some other cool markups languages, thank you.
313  
314  the js community, millions of developers made the npm ecosystem so rich one can build virtually anything with node.
315  
316  If you decide to re-use this repo to build your own stuff, go ahead. No need to credit or link back to this repo/site. Although it would be appreciated.
317  **Don't re-republish stuff pretty much as is though**, it is lame, and shameless.
318  Tweak it, make it your own. Make it so that I wouldn't come across your stuff  and think that it is mine. So that nobody comes across your stuff and somehow finds out it's a louzy copy of someone else lacking added value and personalisation.
319  
320  [codacy-url]: https://app.codacy.com/gh/Apply-Creatures/creature-api-boilerplate/dashboard
321  [codacy-shield]: https://img.shields.io/codacy/grade/9dc0ec9bd55b4091a8b998816ae5b4e7?style=for-the-badge
322  [contributors-shield]: https://img.shields.io/github/contributors/apply-creatures/creature-api-boilerplate.svg?style=for-the-badge
323  [contributors-url]: https://github.com/apply-creatures/creature-api-boilerplate/graphs/contributors
324  [forks-shield]: https://img.shields.io/github/forks/apply-creatures/creature-api-boilerplate.svg?style=for-the-badge
325  [forks-url]: https://github.com/apply-creatures/creature-api-boilerplate/network/members
326  [stars-shield]: https://img.shields.io/github/stars/apply-creatures/creature-api-boilerplate.svg?style=for-the-badge
327  [stars-url]: https://github.com/apply-creatures/creature-api-boilerplate/stargazers
328  [issues-shield]: https://img.shields.io/github/issues/apply-creatures/creature-api-boilerplate.svg?style=for-the-badge
329  [issues-url]: https://github.com/apply-creatures/creature-api-boilerplate/issues
330  [license-shield]: https://img.shields.io/github/license/apply-creatures/creature-api-boilerplate.svg?style=for-the-badge
331  [license-url]: https://github.com/apply-creatures/creature-api-boilerplate/blob/main/LICENSE
332  [score-shield]: https://img.shields.io/ossf-scorecard/github.com/apply-creatures/creature-api-boilerplate?style=for-the-badge
333  [score-url]: https://github.com/apply-creatures/creature-api-boilerplate
334  [repo-size-shield]: https://img.shields.io/github/repo-size/apply-creatures/creature-api-boilerplate?style=for-the-badge
335  [repo-size-url]: https://github.com/apply-creatures/creature-api-boilerplate/archive/refs/heads/main.zip
336  [product-screenshot]: images/apply-creatures-logo.png
337  
338  ## Changelog
339  
340  Changelog see [here](CHANGELOG.md)
341  
342  ## License
343  
344  [![license][license-shield]][license-url]
345  
346  This work is licensed under the [MIT License][license-url].
347  
348  You may use and remix this content, and even build commercial stuff with it.
349  
350  [license-url]: https://mit-license.org/
351  [cc-by-nc-sa-shield]: hhttps://img.shields.io/github/license/apply-creatures/ceature-api-boilerplate?style=for-the-badge
352  
353  If you too produce work and publish it out there, it's clearer to choose a [license](https://choosealicense.com).
354  
355  
356  ```markdown
357  MIT License
358  
359  Copyright (c) 2024 Hirako, Apply Creatures
360  
361  Permission is hereby granted, free of charge, to any person obtaining a copy
362  of this software and associated documentation files (the "Software"), to deal
363  in the Software without restriction, including without limitation the rights
364  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
365  copies of the Software, and to permit persons to whom the Software is
366  furnished to do so, subject to the following conditions:
367  
368  The above copyright notice and this permission notice shall be included in all
369  copies or substantial portions of the Software.
370  
371  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
372  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
373  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
374  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
375  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
376  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
377  SOFTWARE.
378  ```