This frontend is an example of a Single Page Application (SPA) on the Web Platform.
There are lots of ways to build an application, why a SPA? As more and more APIs are added to the Web Platform (known to most as "the browser") more and more code runs on the Web Platform rather than a server or a competing platform like IOS or Android. The language of the Web Platform is JavaScript and a SPA style application is the main way to create apps in the browser.
SPAs execute code in the browser on the users machine, which lets our applications handle spotty network connections, work offline entirely and avoid sending partial data to servers while filling out multi-stage forms. Betting on the web lets us deliver web applications on a truly open platform that are powerful, accessible, and work on a huge range of devices.
Specific to this project, the SPA architecture allows for dynamic behaviour that is needed for us to offer users to trigger their own scans and watch the progress and results appear in their browser.
As the "consumer" part of the API/consumer pair at the heart of the Government as a Platform model, this is assumed to be the first (but never the only) consumer of the backend API. Shaped by user research its needs then inform the building of the API.
In addition to the frontend service, this folder contains files needed to create a good developer workflow. Before diving into the details of the development workflow itself, it's worth talking through the thinking behind what constitutes a "good" workflow.
Applications without APIs project organizational silos into the digital space. With an API, experiences can be created that are centered on the user rather than organizational silos.
By adopting a microservices approach we can lay the foundation for a user centered service, and our new application can fit with the TBS Directive on Management of Information Technology, but the developer workflow around this isn't clear.
One possible way to do local development is to bring up a local copy of Kubernetes in something like Minikube or Kind, and then use a tool like skaffold to run all your services just as you would in production.
This approach can work for small sets of services, but demands extremely powerful dev machines. Since services are developed while running every other service it's easy to build in interdependence into the system.
The big idea here is that realizing the benefits of microservices requires protecting their independence, and that requires developing them independently. This then is the core assumption about what constitutes a "good" workflow: it must be lightweight, and let the developer develop the services independently.
The dev workflow being created here centre's on Docker-compose, a tool that helps developers run multiple containers together.
So here we use docker-compose to bring up the frontend service with a mocked API.
Running those two services behind Envoy allows us a way to present the API at /graphql
just as it would be in production.
The files to support this are the docker compose configuration (docker-compose.yaml
), the config file for Envoy telling it to proxy requests to the API and frontend (envoy-dev.yaml
).
This frontend uses a simple Webpack setup which either runs a hot reloading dev server. To start it, you need to be inside the frontend folder and run the following command:
docker-compose up -d
This will bring up Envoy, the mocked API and the frontend service and detach returning the terminal to the user. As part of this process docker compose will bind mount the frontend folder into the container. This allows changes to the code to be reflected immediately in the running container.
You can see the service running on localhost:3000
and the API running on localhost:3000/graphql
.
If you want to modify the schema you can reach the editor at localhost:3000/editor
.
When you are done:
docker-compose down
npm install
npm test
The linter performs a code analysis that flags programming errors, bugs, stylistic errors, and suspicious constructs.
Style errors are determined by the prettier configuration in .prettierrc
, and plugins exist for automatically formatting code on file save.
npm run lint
The mocker is used to create API data for use on the local instance of Tracker when using docker. It can be used to create specific behaviours in the app in order to test certain behaviours and features.
The frontend is built using React.
React uses JSX allow for the creation of HTML elements inside Javascript.
These elements support the use of variables and any other Javascript inside them by wrapping the Javascript inside of {}
.
The frontend user interface is styled using Chakra. Chakra contains many React components that are used for designing page layouts. Chakra also allows for the use of 'style props', which apply css properties to components. Chakra comes with a default theme, that Tracker extends in /frontend/src/theme/canada.js. The theme contains colour, size, and spacing definitions, along with default component styles and custom component variants.
The frontend communicates to the database API using GraphQL. The primary interactions are queries, used for requesting data from the database, and mutations, used for manipulating data in the database. The faked_schema.js is used to define the inputs and returns, and their corresponding types when running a local copy of Tracker.
The /src/ folder is organized into folders for each page, along with: an app folder for the overall structure of the page; an auth folder for all the login and account creation pages; a components folder for any shared components; and a utilities folder for functions.