2.3.0-beta.6 • Published 3 years ago

horizon-pro-api v2.3.0-beta.6

Weekly downloads
-
License
UNLICENSED
Repository
github
Last release
3 years ago

Status Checks

BranchCode ChecksDeploy
developCode ChecksCodeBuild
qaCode ChecksCodeBuild
hotfixCode ChecksCodeBuild
masterCode ChecksCodeBuild

Table of Contents

Description

horizon-pro-api is an API for Horizon Pro services. The purpose of the API is to provide information related to a sample.

Specifically, this repo provides:

  • Single REST API for 4 former (& separate) API's (asset management, sample, lab reference, reference).

Tech Stack

The Stack

npm.io npm.io npm.io npm.io npm.io

Resources

Installing Node with nvm

It is highly recommended to use nvm to install and manage your Node version(s) locally. See nvm.

Note, in the deploys of the application, the Node version is set by the Node image used within our Dockerfile.

Local Dev Environment Setup Overview

  1. Make sure you have installed and configured all of the necessary tools described in the Developer Start Guide.

  2. Clone this repository to your local machine:
    git clone git@github.com:polarislabs/horizon-pro-api.git

  3. Checkout targeted node version with nvm use. Each repo has a .nvmrc file to support this.

  4. Confirm that your local npm config will enforce the Node version set in the package.json by running npm config set engine-strict true.

  5. Install required dependencies by running npm install.

  6. Copy .env.example to .env in the root of your project. Adjust values as needed as described in Configuration and Environment Variables.

  7. Provision and start backing services.

  8. Run the app.

Running the App

All commands are intended to be run from the root of the horizon-pro-api repository folder.

A valid JWT is required to access secured routes. Please refer to How to Obtain a Valid JWT for instructions on how to obtain the JWT.

Run with npm

The following will get you up and running for development purposes:

  1. Run: npm run develop

  2. Open your browser to localhost + port number configured in your .env file (e.g., http://localhost:3031).

Run with Docker

This requires a local Docker runtime environment (Docker Desktop), which you should already have installed.

  1. Provide the env vars required for Docker build and runtime. See the Environment Variables table below.

  2. Run, or execute manually the steps within, the provided script docker-example.sh which will run them for you.

  3. Open your browser to http://localhost:3031 (or on whatever port you've configured).

Backing Services

To quickly stand up your development environment, you will need Docker. Otherwise, you will have to install and configure backing services separately... and without README documentation assistance.

The project's docker-compose.yml file, together with custom npm scripts, is used by Docker to implement the backing services required by horizon-pro-api.

Local Postgres Database

The following will get you up and running with a local, dockerized, database instance:

  1. Create and run a dockerized database by running npm run docker:up. This will create and run a Postgres image and an associated volume. Note that Docker aggressively caches, so you may need to run docker system prune --volumes (or a less general command) to clear docker data if changes aren't being propagated to your containers/volumes.

  2. Run npm run db:reseed to drop your db, create it, create your schema, and hydrate the database.

After running those commands, you should be able to see seeded data in your database.

Local SQS Instance

Running npm run docker:up, as described in Local Postgres Database, will also create a local, dockerized, SQS-compatible queue service instance.

Production Builds

  1. Build:
    npm run build

  2. Start:
    npm start

    NOTE: In production, the required env vars must be in the environment; this script does not load .env for you. If you are testing this locally, you should run:

    node_modules/.bin/env-cmd node ./build/src/main.js

  3. Open your browser to http://localhost:3031 (substituting whatver port you have configured) to verify it is running correctly.

Configuration and Environment Variables

We are in general following a 12-Factor App configuration approach to configuration management.

Locally, you will need to create a .env file to do this, or populate your environment with the needed env vars in some other way.

The required configuration for the app, based on env vars, can be found in the config.options.ts file.

Basically, all configuration should be stored in the environment. Secure values should never be in the codebase. Secondly, the config module should read in the required var and its value, and throughout the source code, one should get the value from there, not from directlly accessing process.env.

See .env.example for a basic dev env var list with most values.

Env Vars

See the config options file for descriptions and definitions of environment variables.

In addition, the following are relevant for certain operations:

VarDescription
API_ROOTThe root segment of the API routes. Used by smoke tests in CI/CD processes.
LDAP_PASSWORDThe password credential required for obtaining a JWT. Used by smoke tests in CI/CD processes.
LDAP_USERNAMEThe username credential required for obtaining a JWT. Used by smoke tests in CI/CD processes.
NPM_AUTH_TOKENRequired in Dockerfile to install private Polaris packages in the Github registry.
PG_DUMP_DBSee DUMP_AND_MIGRATION_FROM_HP.md
PG_DUMP_HOSTSee DUMP_AND_MIGRATION_FROM_HP.md
PG_DUMP_PASSWORDSee DUMP_AND_MIGRATION_FROM_HP.md
PG_DUMP_PORTSee DUMP_AND_MIGRATION_FROM_HP.md
PG_DUMP_USERSee DUMP_AND_MIGRATION_FROM_HP.md

How to Obtain a Valid JWT

JWTs are issued from the Horizon Pro Auth API. Here's how to obtain a valid JWT:

  1. Open a new browser tab, and open the Network tab inside the browser's debugger window.

  2. Navigate to https://horizonpro.dev.eoilreports.com/login.

    Note, this is the URL for the dev environment. Be sure to adjust the URL as needed.

  3. Login, and find the JWT in the response. It will be a long string of characters preceeded by "Bearer ".

Git Hooks

We are using the husky package to easily setup some git hooks.

See our package.json, we have it configured to act when you push your code.

Documentation

OpenAPI/Swagger

It is best practice to document APIs with the OpenAPI standard. It is common to use Swagger for RESTful APIs.

If enabled, docs are served up on the /api/docs route.

Linting

We are using ESLint to lint our code as we code and when we push our code.

The .vscode/settings.json enables auto-formatting for VSCode. This should format per our lint configuration in the repo. Also, linting is automated, so the lint task will run during the build in the CI/CD pipeline. The build will fail if linting fails.

This app follows the recommended rules defined by us, Polaris Labs Dev Team Nova, in a private eslint package @polarislabs/eslint-config-polaris/node.

For configuring, see .eslintrc.js and .prettierrc.

Changelog

All pull requests should include an update to the CHANGELOG that follows the existing pattern there.

Version numbers will follow Semantic Versioning.

Folder Structure

The folder structure is largely self-documenting. Here are some notes to supplement:

PathDescription
.githubGithub Action configurations.
ciAWS CodeBuild configurations.
confBacking services configurations.
databaseDatabase migrations, imports, seeds...
database/helpersHelper functions that can be used by migrations, etc. Note, these should never be referenced from migrations!
database/importsScripts to do updates/imports against the db apart from the migration process.
database/migrationsKnex migrations to build and populate the database. Will run in deployed environments.
database/seedsKnex seeds to populate data for local development. Will not be run in deployed environments.
docsTechnical documentation, focusing on specific topics beyond the README.
kubernetesKubernetes configurations required for deployment of the service to AWS hosted k8s clusters.
publicPublic assets, e.g. images for the landing page.
scriptsScripts used by the build and/or other scripts. Also contains some helper scripts.
src/commonCross-cutting helpers and types.
src/simpleMessageQueueSupport for publishing to the simple message queue. NOTE: The intent is to move this to a shared package someday; this is why it's not under src/externalServices.
src/utilsUtils are functions that somehow touch the OS, file system, or things outside the /src (e.g., the package.json file).
testTest configurations and integration tests.

See Also

Please refer to the /docs folder for helpful documentation on topics such as debugging, updating seed data, setting up integration tests locally, etc.

Troubleshooting

Testing Error: Cannot Find Module

If you see this when runninng [integration] tests...

Test suite failed to run
    Cannot find module 'src/database/database.constants' from 'component.providers.ts'

... then make sure you aren't using any absolute paths. If you are, fix by replacing absolute paths with relative paths.

Example:

// Wrong - absolute path
import { FOO } from 'src/foo.constants';

// Right - relative path
import { FOO } from '../../../foo.constants';

Testing Error: ConfigService Mock Not Working

The situation is that the ConfigService mock actually works, but Node still tries to load the actual ConfigService. How is this possible???

We ran into this problem when writing unit tests for the SamplePatchService. This service has dependencies on ConfigService and some other services. We thought the problem was that the ConfigService mock was not being properly configured. However, it turns out that one of the dependencies we were mocking had an import dependency on a module that instantiated the ConfigService (i.e., knexfile.ts). Note that import dependencies get resolved on import, before any of the mock factories can be called.

You can see the solution (which was to mock knex and therefore prevent the instantiation of ConfigService) in the samplePatch.service.spec.ts file.