Skip to content

Commit

Permalink
docs(readme): add proper readme
Browse files Browse the repository at this point in the history
  • Loading branch information
Xunnamius committed Aug 28, 2021
1 parent d0f8253 commit 314b1d1
Showing 1 changed file with 224 additions and 3 deletions.
227 changes: 224 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,226 @@
# ghostmeme.api.hscc.bdpa.org
# Ghostmeme Public API

Live API used by solutions to the Ghostmeme NHSCC problem statement.
> Uploaded memes are stored in a public imgur album:
> [https://imgur.com/a/TytqlvJ][1]
Uploaded memes are stored in a public imgur album: https://imgur.com/a/TytqlvJ
The live API used by solutions to the 2021 NHSCC problem statement. It was built
according to [JAMstack principles][2] using TypeScript (JavaScript) and MongoDB.
The production instance is hosted on [Vercel][3] with [MongoDB Atlas][4]. The
code is highly documented. You can clone this repo and run a fully functional
version of this API locally following the instructions below.

> This project has been tested on Linux (Kubuntu). If you encounter any issues
> (especially Windows-specific issues), please [report them][5]. If you're on
> Windows and you're not using WSL, [start using WSL][6].
## Table of Contents

- [Accessing the Production API][7]
- [Running a local instance of the API][8]
- [Project structure][9]
- [Files and directories][10]
- [External scripts][11]
- [Contributing][16]

## Accessing the Production API

- Version 1 root URI: [https://ghostmeme.api.hscc.bdpa.org/v1][22]
- Version 1 documentation and playground with examples:
[https://hscc6xt8cqqf.docs.apiary.io/][23]

## Running a local instance of the API

You should be using the production API (and your real key) for your application.
However, for development purposes, you can also run a local version of the API
to make requests against. This API is entirely self-contained; everything you
need to run it locally is in this repo (except a running MongoDB instance).

To run a local instance of the API:

1. Ensure the latest [NodeJS][24] and [MongoDB][25] are installed.
- Typically, once you run their installers, no further configuration is
required. Easy peasy!
- If you're using WSL on Windows, [read this][26].
- Check out [MongoDB Compass][27]!
2. Clone this repo using your favorite terminal.
3. From the terminal, with the repo as the current working directory, run
`npm install`.
4. Copy the file `dist.env` to `.env`.
- Add your MongoDB connect URI to the MONGODB_URI environment variable in
`.env`.
- Using `mongodb://127.0.0.1:27017/test` as the connect URI should work
out of the box.
- A valid URI looks something like this:
`mongodb://your-server-uri:your-port-number/your-test-db-name`
- It is important that you include **the name of the test database** after
the slash (you can just make something up) like in the above examples.
5. At this point you should test that the API will work on your system. To do
this, run the command `npm test` in your terminal.
6. If all tests passed, you can start up the API in development mode by running
the `npm run dev` command.
7. You can now interact with the API using your browser, [Postman][28], or
otherwise.
- You should see a line on the console that looks like
`ready - started server on http://<HOST:PORT>`. Use that URI at the end to
access the API.
- If you're using MongoDB Compass, you'll be able to visually explore the
dummy database's data at this point.

## Project structure

This project uses the following technologies:

- [Node and NPM][24] to run JavaScript locally
- [TypeScript][29] for producing typed JavaScript
- [Babel][30] for compiling (transpiling) TypeScript + ESNext syntax
- [Git][32] for version control and deploying to production
- [ESLint][33] for TypeScript and JavaScript linting
- [Webpack][34] for tree-shaking and asset bundling
- [JSX][35], [React][36], and [Next.js][37] for modern web development
- [MongoDB][38] [Node driver][39] for database access
- [Jest][40] for unit and integration testing
- [API Blueprint][41] (APIB) for describing the API
- [JSON][42] (JavaScript Object Notation) for storing and transferring
information

### Files and directories

The various `tsconfig.*.json` files control the TypeScript settings used when
type checking the project, building the docs, etc.

`package.json` and `package-lock.json` are used by NPM to describe the
dependencies that will be automatically installed when executing `npm install`.

`next.config.js` returns a JSON object used to configure [Next.js][45].
`vercel.json` serves a similar purpose.

`.env.example` is the [distributed environment file][46]. It's meaningless on
its own, but when copied and renamed to `.env`, it will be used by the API to
define certain environment variables.

The files listed in `.gitignore` are ignored when Git uploads your code to the
internet. This is useful for hiding secrets like the `.env` file.
`.gitattributes` is another Git configuration file.

`next-env.d.ts` is a TypeScript types file. It's a special type of JavaScript
file that globally defines TypeScript types used by other files. The `types/`
folder serves a similar purpose.

`LICENSE` is an license file that says you can do whatever you want with the
code in this project. Might switch to a CopyFair license eventually.

`babel.config.js` returns a JSON object used to configure [Babel][48], our
transpiler. `webpack.config.js` returns a JSON object used to configure how
[Webpack][49] builds the [external scripts][11]. `jest.config.js` returns a JSON
object used to configure [Jest][50], our [test runner][51]. `.eslintrc.js`
returns a JSON object used to configure [ESLint][52], our code correctness
checker or "linter".

`.codecov.yml`, `.editorconfig`, `.prettierignore`, `.spellcheckignore`,
`.vercelignore`, and all `*.config.js` files are configuration files for various
other tools (google 'em!).

`data/` contains any dummy data used during activity simulation not covered by
[Faker.js][31].

`docs/` contains further documentation.

`external-scripts/` contains the source code for all the [external scripts][11].
`external-scripts/bin/` is created when running `npm run build-externals`, which
compiles the scripts in `external-scripts/` into `external-scripts/bin/`.

`lib/` contains TypeScript modules shared between projects. These are candidates
for becoming new NPM packages.

`public/` contains files served directly by Vercel out of band.

`src/` contains the source code of the application. `test` contains the unit and
integration tests for the API. `src/backend` contains backend business logic and
the database ORM layer (kept thin thanks to MongoDB). `src/frontend` contains
frontend business logic and the API client ORM layer for the API's tools UI.
`src/pages` contains React (JSX) TypeScript code (`.tsx` files). `src/pages/api`
contains the actual API endpoints. The directories and files are so named to
take advantage of [Next.js's dynamic routing][57].

### External scripts

The files found under `external-scripts/bin` are independently bundled
standalone executables meant to be invoked manually by processes external to the
app itself (usually as cron jobs).

These scripts must be configured using the appropriate `.env` variables. See
`dist.env` for details.

You can use `npm run` to build any external scripts. The executable will be
placed in `external-scripts/bin`:

```Bash
npm run build-externals
```

> Warning: when you change `.env` you must (re-)build external scripts using the
> above command.
All executables under `external-scripts/bin` can be run like so:

```Bash
node external-scripts/bin/script-name-here.js
```

Currently, the following external scripts exist:

- `prune-logs.js` - Responsible for ensuring the mongodb request-log collection
never grows too large. Should be run every hour or so.
- `ban-hammer.js` - Responsible for rate limiting (banning) keys and ips that
hit the API too often. Should be run every minute.

## Contributing

**New issues and pull requests are always welcome and greatly appreciated!** See
[CONTRIBUTING.md][58] and [SUPPORT.md][59] for more information.

[1]: https://imgur.com/a/TytqlvJ
[2]: https://jamstack.org/
[3]: https://vercel.com
[4]: https://www.mongodb.com/cloud/atlas
[5]: https://github.com/nhscc/ghostmeme.api.hscc.bdpa.org/issues/new
[6]: https://docs.microsoft.com/en-us/windows/wsl/install-win10
[7]: #accessing-the-production-api
[8]: #running-a-local-instance-of-the-api
[9]: #project-structure
[10]: #files-and-directories
[11]: #external-scripts
[16]: #contributing
[22]: https://ghostmeme.api.hscc.bdpa.org/v1
[23]: https://hscc6xt8cqqf.docs.apiary.io/
[24]: https://nodejs.org/en
[25]: https://docs.mongodb.com/manual/installation
[26]:
https://docs.microsoft.com/en-us/windows/wsl/tutorials/wsl-database#install-mongodb
[27]: https://docs.mongodb.com/compass/master/install
[28]: https://www.postman.com/
[29]: https://www.typescriptlang.org/
[30]: https://babeljs.io/
[32]: https://git-scm.com/
[33]: https://eslint.org/
[34]: https://webpack.js.org/
[35]: https://reactjs.org/docs/introducing-jsx.html
[36]: https://reactjs.org/
[37]: https://nextjs.org/
[38]: https://www.mongodb.com/
[39]: https://mongodb.github.io/node-mongodb-native
[40]: https://jestjs.io/
[41]: https://apiblueprint.org/
[42]:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON
[45]: https://www.npmjs.com/package/next
[46]: https://www.npmjs.com/package/dotenv
[48]: https://babeljs.io
[49]: https://webpack.js.org
[50]: https://jestjs.io
[51]: https://jestjs.io/docs/en/getting-started
[52]: https://eslint.org
[57]: https://nextjs.org/docs/routing/dynamic-routes
[58]: ./CONTRIBUTING.md
[59]: .github/SUPPORT.md
[31]: https://www.npmjs.com/package/faker

0 comments on commit 314b1d1

Please sign in to comment.