Skip to content

nhscc/drive.api.hscc.bdpa.org

Repository files navigation

BDPADrive Public API

The live API used by solutions to the 2022 NHSCC problem statement. It was built according to JAMstack principles using TypeScript (JavaScript) and MongoDB. The production instance is hosted on Vercel with MongoDB Atlas. 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. If you're on Windows and you're not using WSL, start using WSL.

Table of Contents

Accessing the Production API

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 and MongoDB are installed.
    • Typically, once you run their installers, no further configuration is required. Easy peasy!
    • If you're using WSL on Windows, read this.
    • Check out MongoDB Compass!
  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 .env.example 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.
    • You may need to add values for a few other environment variables. Pay attention to any error messages you receive.
  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, 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 to run JavaScript locally
  • TypeScript for producing typed JavaScript
  • Babel for compiling (transpiling) TypeScript + ESNext syntax
  • Git for version control and deploying to production
  • ESLint for TypeScript and JavaScript linting
  • Webpack for tree-shaking and asset bundling
  • JSX, React, and Next.js for modern web development
  • MongoDB Node driver for database access
  • Jest for unit and integration testing
  • API Blueprint (APIB) for describing the API
  • JSON (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. vercel.json serves a similar purpose.

.env.example is the distributed environment file. 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, our transpiler. webpack.config.js returns a JSON object used to configure how Webpack builds the external scripts. jest.config.js returns a JSON object used to configure Jest, our test runner. .eslintrc.js returns a JSON object used to configure ESLint, 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.

docs/ contains further documentation.

external-scripts/ contains the source code for all the external scripts. 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.

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 .env.example for details.

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

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:

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 and SUPPORT.md for more information.