Skip to content
Atlas-connect-express application boilerplate with GraphQL, PostgreSQL and a layered architecture
JavaScript HTML Other
Branch: master
Clone or download
Pull request Compare This branch is 1 commit ahead, 1 commit behind mtmendonca:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
api
app
infrastructure/dev
.dockerignore
.env.sample
.flowconfig
.gitignore
.nvmrc
.travis.yml
README.md
docker-compose-services.yaml
docker-compose.yaml
start

README.md

Atlassian Add-on using Express + some sugar

License: MIT Build Status

Tech

Quick setup

Dependencies

Nodejs v10.x: Use nvm if you can, it's handy for switching between node versions A Jira Cloud development instance: Click here to get one. Assuming you used nvm, activate v10 and install Yarn globally:

$ nvm install 10
$ nvm use 10
$ npm install -g yarn

Create a copy of .env.sample as .env Create a copy of api/credentials.json.sample as credentials.json Edit credentials.json. To get an API Token follow these instructions

{
    "hosts": {
        "<YOUR JIRA INSTANCE ENDPOINT>": {
            "product": "jira",
            "username": "<YOUR EMAIL>",
            "password": "<YOUR API TOKEN>"
        }
    }
}

Run yarn in api and app to install dependencies.

Start the docker-compose stack

$ ./start

The script above will

  • Install node dependencies on the api and app directories
  • Deploy Postgresql and Redis containers
  • Start the server and web applications on containers
  • Start an nginx reverse proxy that redirects /app requests to the web container, and everything else to the api container

Use ACE's AC_OPTS environment variable on .env to control ACE's behaviour. With the current value of AC_OPTS=force-reg,force-dereg an Ngrok tunnel will be created and used as your application's enpoint during development. Use AC_OPTS=no-auth to start the stack locally, skipping authentication, and USE_GRAPHQL_MOCKS=true to mock graphql queries and mutations.

This repo comes with a sample create-react-app application that shows some user info and lists the first 10 jira issues from your configured instance.

Production deployment

When deploying to production make sure you replace atlassian-connect.json with a version of the file that matches your production environment.

Docker

Build the production-ready container using Dockerfile.production

Standalone

yarn build and yarn prod start the api listening on the configured port.

Architecture

This boilerplate creates a dependency injection container named ioc and adds it to express' req, used in routes and graphql resolvers. This container has methods that return the bootstrapped dependencies placed under:

  • api/src/adapters for db and redis connections: getAdapter('adapter-file-name')
  • api/src/domains for domain classes for business logic getDomain('domain-file-name')
  • api/src/models for sequelize data models getModel('model-file-name')
  • api/src/services for external integrations getService('service-file-name').

AddonService is a wrapper around ace.httpClient defined in api/src/factories/AddonServiceFactory.js and it gets loaded into the IoC container in the addon.js middleware function, due to its per-request nature.

ACE's middleware also includes a context object in req which contains jira's context data. In essence, the following variables are added to express' req object:

{
  ioc: ContainerInterface,
  context: ACEContext,
  ace: ?Object,
}

api/entrypoint.sh runs a database migration prior to launching the stack. DB Migrations are created using knex and the node script db is an alias to it.

AddonService

The AddonService instance you get from req.ioc.getService('Addon') gives you get, post, put and delete methods that proxy ace's httpClient methods. There are utility methods in api/src/utils/addonServiceUtils:

  • getBodyJson: returns jira api response body as an object
  • getResultWithoutPagination: Paginates through jira's response until there are no more records left and returns the accumulated responses as an object

JiraClient

api/services/JiraClient's instance obtained with ioc.getService('JiraClient') is a Jira Api client wrapper to be used outside an instance's http request lifecyle such as scheduled jobs. Use this class' http method wrappers to interact with Jira's api providing a clientKey and JiraClient will look up the right information from AddonSettings, sign the request and return the resulting request's response body in a promise.

Yarn scripts

/api

command purpose
dev Starts the stack locally according to the AC_OPTS config in .env
dev-debug same as dev but with node's --inspection enabled and listening on port 9229
test Runs automated tests
cover Runs automated tests and outputs test coverage with istambul
db Alias to knex
migrate Runs the latest migrations
create-migration <migration-name> Creates an empty database migration on /db/migrations
build Creates production build in api/dist/
prod Starts production build by running node api/dist/src/app.js

/app

Default create-react-app scripts

You can’t perform that action at this time.