Getting Started with Development
Before starting, make sure you have the following requirements:
From the root of the repository, run the following command:
Setting up the environment variables
config/ directory, create a copy of the
config.env.sample file, named
config.env. Replace the placeholders with the appropriate values. For more information on the environment variables, see the environment documentation.
Starting backend services
The applications need to connect to the following services:
Information on setting up these services can be found in the services documentation.
The repository is organized as a monorepo using tooling from Nx. A brief overview of the repository structure and using Nx is presented here.
apps directory contains code for the high level applications that are a part of BioSimulations and BioSimulators. An application is code that is deployed independently, either as a website, API, or backend service. The applications are implemented using TypeScript, except the COMBINE API, which is implemented using Python. See the README for the COMBINE API for more information about installing, running, and editing the COMBINE API.
The applications in the repository are:
- platform: The web application for BioSimulations
- dispatch: The web application for runBioSimulations
- simulators: The web application for BioSimulators
- account: The web application for BioSimulations account management (not currently functional)
- account-api: The API for BioSimulations account management (not yet implemented)
- api: The BioSimulations API
- simulators-api: The BioSimulators API
- combine-api: The COMBINE API (Implemented in Python)
- dispatch-service: The backend service for running simulations
- mail-service: The backend service for sending email notifications to users
libs directory contains code that can be used by multiple applications. Each library contains a
README.md file that describes its purpose. The libraries are implemented using TypeScript.
To view the organization of the apps and libraries, run the following command:
Library dependency restrictions
To enforce proper separation of concerns and manage dependency trees, BioSimulations and BioSimulators employ constraints on the libraries that can be used by each application.
project.json file for each application and library, there are tags that are used to categorize the scope and type of the libraries. In general, the following tags are used:
platform: This tag can be one of
webtag indicates that the app or library is designed to run in browsers, and contains code that is specific to the web, such as Angular libraries, or code that makes use of Web APIs. These libraries can only be imported by apps and libraries that have the
servertag indicates that the app or library is designed to run on the server, and contains code that is specific to the server, such as file system interaction, interaction with the database, or imports of backend libraries. These libraries can only be imported by apps and libraries that have the
anytag indicates that the app or library can be used by both the web and server, and contains platform-agnostic code, such as utilities or data model definitions.
scope: This tag is used to enforce separation of concerns between applications. Each application is assigned a scope and can only import libraries that are in the same scope. The scope 'shared' indicates that the library can be imported by any application. Libraries can also be assigned a specific scope to ensure that helper libraries are encapsulated by the parent library and cannot be imported directly by an application.
type: This tag can be used to enforce proper library organization. For example, a library that has a
uiis intended to provide generic UI components that can be used by multiple applications. Therefore, libraries with a type of
uican be restricted from importing libraries with a
datamodelwhich defines data models, to ensure that the UI components do not depend on the data models. The possibles types of libraries are
feature: Libraries that implement specific features or smart UI (ui that is aware of the data model)
ui: Libraries that provide generic UI components (not aware of the data model)
datamodel: Libraries that define data models
data-access: Libraries that connect to backend services, or manage state
util: Libraries that provide utility functions across applications
Additional tags can be added to the
project.json files for each application and library. These rules are enforced by the linting rules defined in the eslint rules. For more information on how to use tags, see the Nx documentation.
Using the Nx CLI
This project uses Nx. Below is a brief introduction to using Nx with this project.
Generate a skeleton for an application
nx g @nrwl/angular:app my-app to generate an Angular application (front-end).
nx g @nrwl/nest:app my-nest-app to generate a NestJS application (back-end).
Generate a skeleton for a library
nx g @nrwl/angular:lib my-lib to generate an Angular library.
nx g @nrwl/nest:lib my-nest-lib to generate a NestJS library.
nx g @nrwl/node:lib my-node-lib to generate a NodeJS library.
nx g @nrwl/js:library --name=my-ts-lib --buildable to generate a platform agnostic typescript library
Libraries are sharable across libraries and applications. They can be imported as
Generate skeletons for application components
Nx can be used to generate skeletons for components as well. This includes front-end components, backend-end controllers, services, and various Angular and NesJS structures. For more information on generating components, see the [Nx documentation]https://nx.dev/generators/using-schematics).
Run a development server
ng serve my-app to run a development server for the application.
To run an front end application that connects to a locally running backend service, run both applications in two different terminals. The endpoints documentation describes how the applications determine which endpoints to connect to.
Lint an application or library
nx lint my-app to lint an application or library.
nx affected:lint to lint all projects affected by your recent changes.
Run unit tests for an application or library
nx test my-app to execute the unit tests via Jest.
nx affected:test to execute the unit tests affected by your recent changes.
Run end-to-end tests for an application
nx e2e my-app to execute the end-to-end tests via Cypress.
nx affected:e2e to execute the end-to-end tests affected by your recent changes.
Build an application
nx build my-app to build the project. The build artifacts will be stored in the
dist/ directory. Use the
--prod flag for a production build.
Mapping the dependencies of the applications and libraries
nx dep-graph to see a diagram of the dependencies of your projects.