Skip to content

Architecture

Alejandra Gonzalez-Beltran edited this page Nov 26, 2019 · 14 revisions

Context

The SciGateway frontend provides an interface for users to talk to multiple systems accessing data and compute resources for large science facilities, including:

  • it allows users to explore their data
  • it allows users to explore open data
  • ask for new virtual machines via the virtual machine manager
  • interact with third party systems for logging in.

The main consideration for the frontend is that multiple versions of the UI may be deployed at different institutions and they may have different data needs. For example, one deployment may not need an instance of ICAT but use a different data system instead.

For this reason the SciGateway frontend uses a micro-frontend based architecture. This means that micro-frontends (which can also be thought of as plugins) can be developed independently by different teams and different deployments can use different plugins.

Containers

The first point of contact for users will be the parent app, this will actually have very little functionality of it's own but instead will be responsible for pulling in plugins and mounting them. The parent app will also potentially have to direct traffic to other supporting services as well.

In order to avoid the CORS problem with different plugins and services being hosted on different machines then it will be important to put in some form of API gateway. This might range from a full API gateway solution like Kong or Gravitee, but also more simply a proxying Nginx server.

Most of the functionality of the frontend will be contained in the plugins and hence it is not possible to outline what the system will do here. The primary functionality of the SciGateway frontend is to handle authentication and load plugins provided at the time of deployment.

Components

The site itself will be primarily made up of a top-level appbar and a navigation menu on the left. Plugins can then register routes into the parent app. The plugins themselves will be mounted inside the main are of the app.

Notifications will be presented to the user as a toastr in the bottom right.

The parent app will be responsible for authentication, navigation and notifications. Outside of that, the plugins will be responsible for their specific bits of functionality.

Deployment

To think about how the frontend will be deployed then we need to revisit the container breakdown of the system. The parent app and the api gateway will be deployed on to the same instance but apart from that then there is no restriction of where the other parts are located.

The purpose of the api gateway is to allow plugins to be deployed at different locations, similarly, services can also be located on different machines. The proxying done by the api gateway should hide most of this complexity.

Alternatively, all of the plugin code can be packaged up together and served out of the same machine - the downside of this being that the plugins can't update independently or load-balance independently.

Architectural Background

Technologies

The technology stack selection has been based on the principles of:

  • Making use of Open Source Software
  • Selecting modern, well supported frameworks to ensure long term sustainability (within the bounds of the previous principle)
  • Fitting in with STFC processes where there are clearly defined technology choices for consistency

Tools

  • Create React App for the initial site template
  • Jest unit testing and coverage
  • Cypress end-to-end testing
  • React Storybook
  • React Storybook Info addon
  • ESLint with the Typescript rule set
  • Prettier code styling
  • Husky for pre-commit hooks
  • GitHub for Agile tracking
  • GitHub for version control and issue management
  • GitHub for the documentation wiki

Languages

  • JavaScript
  • Markdown

Frameworks

  • React
  • Redux
  • React-Router
  • Redux-thunk
  • Material UI
  • Single SPA (micro-frontend framework)

Quality

Coding Standards

Static code analysis is done by running ESLint against the code with the Typescript rule set. Code styling is done with Prettier to avoid debates on code styling. These are both enforced as pre-commit hooks with the --fix option turned on so as much as possible is automatically fixed. This ensures the static code analysis violations remain at zero unless explicitly ignored.

Unit testing is all done with Jest which provides code coverage information using the --coverage flag, this generates an LCOV report with all the coverage information.

All code including documentation should be peer-reviewed, as such all work must be done on a branch and a pull request created in order to review the code before merging into the master branch

Branches should use the naming convention feature/{descriptive name}-#{issue number}. By adding the issue number to the end it allows people to link requirements to code.

When creating a pull request you should also add the comment

connect to #{issue number}

to the description to link the pull request to the issue. It is useful to change this to

Closes #{issue number}

if your pull request completely closes an issue as then GitHub will automatically close the issue once the pull request is approved and merged.

Reviewers should build the code and run the tests, they should also take note of the impact on code coverage. The aim is to maintain a high level of coverage (e.g. over 90% is good) but whilst being pragmatic, it is not an exercise in getting a high number but rather making sure the new code is sufficiently tested for maintainability.

Security

The SciGateway frontend is only available to authorised users, as such it will need to implement a login capability (usually talking to a back-end web api to obtain an authorisation token but potentially using a redirect to an authorisation site and returning with a token). Therefore, the site should be hosted over https to ensure credentials are not transmitted in plain text.

As most of the functionality will be provided by the plugins (and the associated back-end services they communicate with), then it will be their responsibility to ensure they don't expose vulnerabilities (e.g. SQL/JS injection). The parent app will not be able to control what the plugin is capable of.

Testing

See the Project Test Plan for more details about testing the system.

Attitude towards bugs and technical debt

Bugs severely affect the maintainability of the system, as far as is practical we should seek to have a zero bug system - this means that when a bug is identified then it gets prioritised to the top of the backlog and dealt with as soon as possible. If the bug is deemed not to be a priority then it will be marked as won't fix and closed.

This approach should ensure that the number of bugs doesn’t become un-manageable and then ignored because they seem unsolvable.

The same approach should be employed with technical debt, we should seek to minimise technical debt so the system is more maintainable. This should allow us to develop faster because we aren’t weaving new features into an existing fragile system. The one caveat with this is that a level of pragmatism needs to be taken depending on the timescales and progress needed for the project, but remembering that every un-addressed issue will slow the project down at some point in the future.

Clone this wiki locally