-
Notifications
You must be signed in to change notification settings - Fork 55
GraphQL Flow
Our application uses GraphQL to make queries and mutations across the application. It controls the flow of data between the frontend, backend, and database for almost all logged-in users (i.e., it doesn't handle anonymous requests; we have separate Controller
classes for those.)
GraphQL has extensive documentation which you may find helpful: https://graphql.org/learn/
This page aims to document SimpleReport's specific GraphQL implementation for engineers new to the project.
GraphQL has both queries and mutations. Queries just return data from the database, while mutations let you edit the data in our database. A query example would be fetching the test queue for a given facility, while a mutation would be something like adding a new patient.
Our frontend calls queries and mutations which are sent to various Resolver
classes on the backend. These resolvers connect with our database, either directly or indirectly, to fetch or manipulate data as needed. The mutation/query definitions are shared in a contract between the frontend and backend, defined in .graphqls
files. The frontend must call these operations exactly as specified in the GraphQL file, and the backend must define a method to implement them.
We define our GraphQL mutations and types in main.graphqls
, admin.graphqls
, and wiring.graphqls
.
main.graphqls
defines most of the interactions seen by end users - adding patients, facilities, tests, api users, etc, as well as fetching data like tests, organization name, and the patient list. It also defines several types
that are used across different queries and mutations, such as Organizations and Facilities. These types are usually closely related to our database tables, but that's an artificial construct - there's nothing that directly ties the two.
admin.graphqls
defines superadmin or support-capable queries and mutations. These include mutations like resending a group of results to ReportStream, creating or identity verifying a new organization, and marking api users or facilities as deleted or undeleted.
wiring.graphqls
defines some common types for GraphQL usage, including permission levels, roles, and some statuses. It does not currently define any mutations or queries.
Whenever these .graphqls
files are changed, you need to run yarn codegen
on the frontend. There's an additional generated file, graphql.tsx
that converts all our queries, mutations, and types to Typescript-compatible types. Before the team used this generated file, to use a mutation or query on the frontend you'd need to first re-define the mutation/query as a Typescript type within your frontend file. It was very annoying, so just use the generated types instead!
Let's follow the path of a GraphQL query all the way through our application. (Note that this was written 12/1/2021, apologies if it's out of date by the time you're reading this.)
In this example, let's look at fetching the list of users on the Manage Users
page.
Here I am testing out a local change
- Getting Started
- [Setup] Docker and docker compose development
- [Setup] IntelliJ run configurations
- [Setup] Running DB outside of Docker (optional)
- [Setup] Running nginx locally (optional)
- [Setup] Running outside of docker
- Accessing and testing weird parts of the app on local dev
- Accessing patient experience in local dev
- API Testing with Insomnia
- Cypress
- How to run e2e locally for development
- E2E tests
- Database maintenance
- MailHog
- Running tests
- SendGrid
- Setting up okta
- Sonar
- Storybook and Chromatic
- Twilio
- User roles
- Wiremock
- CSV Uploader
- Log local DB queries
- Code review and PR conventions
- SimpleReport Style Guide
- How to Review and Test Pull Requests for Dependabot
- How to Review and Test Pull Requests with Terraform Changes
- SimpleReport Deployment Process
- Adding a Developer
- Removing a developer
- Non-deterministic test tracker
- Alert Response - When You Know What is Wrong
- What to Do When You Have No Idea What is Wrong
- Main Branch Status
- Maintenance Mode
- Swapping Slots
- Monitoring
- Container Debugging
- Debugging the ReportStream Uploader
- Renew Azure Service Principal Credentials
- Releasing Changelog Locks
- Muting Alerts
- Architectural Decision Records
- Backend Stack Overview
- Frontend Overview
- Cloud Architecture
- Cloud Environments
- Database ERD
- External IDs
- GraphQL Flow
- Hibernate Lazy fetching and nested models
- Identity Verification (Experian)
- Spring Profile Management
- SR Result bulk uploader device validation logic
- Test Metadata and how we store it
- TestOrder vs TestEvent
- ReportStream Integration
- Feature Flag Setup
- FHIR Resources
- FHIR Conversions
- Okta E2E Integration
- Deploy Application Action
- Slack notifications for support escalations
- Creating a New Environment Within a Resource Group
- How to Add and Use Environment Variables in Azure
- Web Application Firewall (WAF) Troubleshooting and Maintenance
- How to Review and Test Pull Requests with Terraform Changes