Skip to content

NHSDigital/clinical-data-gateway-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

222 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Clinical Data Gateway API

CI/CD Pull Request Quality Gate Status

The Clinical Data Gateway API exposes GP Connect services over the internet via the NHS API Management platform. It receives requests from consumer systems, validates and enriches them using NHS spine services, and forwards them to the patient's GP provider system to retrieve structured clinical records.

For detailed GP Connect specifications, see GP Connect specifications for developers.

Table of Contents

Architecture Overview

When a consumer system sends a request to the Gateway API, the following orchestration takes place:

sequenceDiagram
    participant Consumer as Consumer System
    participant Gateway as Gateway API
    participant PDS as PDS FHIR API
    participant SDS as SDS FHIR API
    participant Provider as GP Provider System

    Consumer->>+Gateway: POST /patient/$gpc.getstructuredrecord
    Gateway->>+PDS: Look up patient's GP practice (ODS code)
    PDS-->>-Gateway: GP practice ODS code
    Gateway->>+SDS: Look up provider ASID & endpoint (provider ODS)
    SDS-->>-Gateway: Provider ASID + endpoint
    Gateway->>+SDS: Look up consumer ASID (consumer ODS)
    SDS-->>-Gateway: Consumer ASID
    Gateway->>+Provider: Forward request with ASIDs
    Provider-->>-Gateway: FHIR Bundle (structured record)
    Gateway-->>-Consumer: FHIR Bundle response
Loading

Key NHS services used:

Service Purpose
PDS FHIR API Looks up the patient's registered GP practice code
SDS FHIR API Resolves provider/consumer endpoint details and ASID values
GP Provider System The patient's GP system that returns the clinical record

Tech Stack

Component Technology
Language Python 3.14+
Web framework Flask
Dependency management Poetry
API specification OpenAPI 3.0
Data models FHIR (Fast Healthcare Interoperability Resources)
Infrastructure Terraform, Docker
Testing pytest, pytest-bdd, Pact, Schemathesis
Static analysis mypy (strict mode), Ruff

Repository Structure

├── gateway-api/                  # Application code and tests
│   ├── openapi.yaml              # OpenAPI specification
│   ├── pyproject.toml            # Python project and dependency definitions
│   ├── src/
│   │   ├── gateway_api/          # Flask application
│   │   │   ├── app.py            # Flask routes and entrypoint
│   │   │   ├── controller.py     # Orchestrates PDS → SDS → Provider calls
│   │   │   ├── get_structured_record/  # Request model
│   │   │   ├── pds/              # PDS FHIR API client
│   │   │   ├── sds/              # SDS FHIR API client
│   │   │   ├── provider/         # GP Provider client
│   │   │   └── common/           # Shared utilities and error handling
│   │   └── fhir/                 # FHIR resource data models
│   ├── stubs/                    # API stubs for local testing
│   └── tests/                    # Test suites (see Testing section)
├── infrastructure/               # Terraform modules and Docker images
│   ├── environments/             # Environment-specific config (dev, preview)
│   ├── images/                   # Dockerfiles (build container, gateway-api)
│   └── modules/                  # Terraform modules
├── proxygen/                     # API proxy deployment configuration
├── scripts/                      # Build, test, and CI/CD scripts
└── bruno/                        # Bruno API collection for manual testing

For more detail on the test suites, see the tests README.

Setup

Clone the Repository

git clone git@github.com:NHSDigital/clinical-data-gateway-api.git
cd clinical-data-gateway-api

Dev Container (Recommended)

The project is configured to run inside a Dev Container defined in .devcontainer/devcontainer.json. When you open the project in VS Code with the Dev Containers extension installed, you will be prompted to reopen in the container. This automatically installs all required libraries and tools.

The dev container sits on the same network, gateway-local, as the gateway-api container, if deployed. Docker DNS will resolve http://gateway-api to the deployed Gateway API.

Note

WSL users: Configure the Dev Containers extension with {"dev.containers.executeInWSL": true}, clone the repository into the WSL filesystem, connect VS Code to WSL first, then open the repository folder and build the container.

Prerequisites

  • A container runtime such as Docker (Linux/WSL) or Colima (macOS)

Usage

The project uses make targets to build, deploy, and manage the application. Run these from the repository root:

Command Description
make dependencies Install all project dependencies via Poetry
make build Type-check, package, and build the Docker image
make env Create a .env to be consumed when starting the app, e.g. make deploy
make deploy Build and start the Gateway API container using the environment variables defined in .env
make clean Stop and remove the Gateway API container
make config Configure the development environment

API Endpoints

Once deployed, the API exposes:

Method Path Description
POST /patient/$gpc.getstructuredrecord Retrieve a patient's structured clinical record
GET /health Health check endpoint

The full API schema is defined in gateway-api/openapi.yaml.

Environment Variables

Make commands help build the .env and .env.test files used to populate the required environment variables.

.env

make deploy will feed the .env variables in to the app's environment.

Environment variables control whether stubs are used in place of the real PDS, SDS, and Provider services during local development.

Variable Description
PDS_URL The URL for the PDS FHIR API; set as stub to use development stub.
PDS_API_TOKEN Leave unset in development environment.
PDS_API_SECRET Leave unset in development environment.
PDS_API_KID Leave unset in development environment.
SDS_URL The URL for the SDS FHIR API; set as stub to use development stub.
SDS_API_TOKEN Leave unset in development environment.
PROVIDER_URL The URL for the GP Provider; set as stub to use development stub.
CDG_DEBUG true, return additional debug information when the call to the GP provider returns an error.

See make env-* in scripts/env/app/env.mk for the commands that will write these variables to a file.

Note: FLASK_HOST and FLASK_PORT are hardcoded in to the Dockerfile. These are for container, and do not need adjusting.

.env.test

Variable Description
BASE_URL Protocol, hostname and port for the running API (e.g. http://localhost:5000, or http://gateway-api:8080 from within the devcontainer)
APIGEE_ACCESS_TOKEN An access token to Apigee API used by pytest_nhds_apim, fed from the environment variables at run time.
PROXYGEN_API_NAME The name of the API defined in Proxygen. Used by pytest_nhsd_apim to run tests against, fed in the CLI arguments in make test-*
PROXY_BASE_PATH The suffix of the proxy instance being deployed. Used by pytest_nhsd_apim to run tests against, fed in the CLI arguments in make test-*
BASE_URL Set if targeting a locally deployed application; otherwise, leave unset.
TARGET_ENV Either local or remote, to inform the HTTP client used by the tests how to behave - e.g. add auth headers, etc.
REMOTE_TEST_USERNAME The test user through which the tests will be authenticated against when run against a remote target.

Testing

The project has five test suites, each targeting a different layer of confidence. The API container must be running for all suites except unit tests.

Command Suite Framework Description
make test-unit Unit pytest Tests individual modules in isolation
make test-acceptance Acceptance pytest-bdd BDD tests using Gherkin feature files
make test-integration Integration pytest HTTP-level tests against the running API
make test-schema Schema Schemathesis Auto-generated tests from the OpenAPI spec
make test-contract Contract Pact Consumer/provider contract verification
make test All Runs every test suite

For detailed information about each test type, directory layout, and how to run them, see the tests README.

Design

Stubs

The gateway-api/stubs/ directory contains stub implementations of the external services (PDS, SDS, GP Provider). These are used during local development and testing so that tests can run without connecting to live NHS services. Stubs are activated via environment variables.

Architecture Decision Records

Significant design decisions are documented as Architecture Decision Records (ADRs). The ADR format follows the NHS England Repository Template convention.

CI/CD

The project uses GitHub Actions for continuous integration and deployment, organised into reusable stages:

Workflow Trigger Purpose
Pull Request PR opened/reopened Runs commit checks, tests, build, and acceptance
Publish PR merged to main Creates a release and tags the artefact
Deploy Manual dispatch Deploys a selected tag to an environment

For full details on each workflow and composite action, see the CI/CD documentation.

Proxygen

To be able to use the load-tests or local-tests, you will need to have Proxygen access setup.

  • Please follow the guide here
  • When the devcontainer has built, the Proxygen configuration is created on the host at ~/gateway/ptl/.proxygen and bind-mounted into the container as ~/.proxygen.
  • For settings:
    • Set the api value
    • endpoint_url and spec_output_format should be already set.
  • For credentials:
    • Set the base_url, client_secret, password and username values.
    • Remove unused fields.

Licence

Unless stated otherwise, the codebase is released under the MIT License. This covers both the codebase and any sample code in the documentation. See LICENCE.md.

Any HTML or Markdown documentation is © Crown Copyright and available under the terms of the Open Government Licence v3.0.

About

Code supporting the Clinical Data Sharing Gateway APIs

Resources

License

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors