You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .github/pull_request_template.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,3 +13,4 @@
13
13
## Review checklist
14
14
15
15
-[ ] Check database queries are correctly scoped to current_provider
16
+
-[ ] If this changes the gateway API (`/api/v1/`), confirm whether it is a breaking change — if so, a new major version (`/api/v2/`) is required (see [ADR-006](../docs/adr/ADR-006-Gateway_API_versioning_strategy.md))
Copy file name to clipboardExpand all lines: docs/adr/ADR-006-Gateway_API_versioning_strategy.md
+16-17Lines changed: 16 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -23,47 +23,46 @@ The API is currently at v1, mounted at `/api/v1/`. As the system evolves, API ch
23
23
24
24
### Options
25
25
26
-
#### Option 1: URL-based major versioning with major.minor convention (chosen)
26
+
#### Option 1: URL-based major versioning only (chosen)
27
27
28
-
Use a URL prefix for the major version (`/api/v1/`, `/api/v2/`). Adopt a `major.minor` convention for communicating the nature of changes:
28
+
Use a URL prefix for the major version (`/api/v1/`, `/api/v2/`):
29
29
30
-
-**Non-breaking changes** (new endpoints, new optional fields): increment the minor version in the OpenAPI `version` string (e.g. `1.0` → `1.1`). The URL does not change.
30
+
-**Non-breaking changes** (new endpoints, new optional request parameters, new response fields): no version change required. The URL does not change.
31
31
-**Breaking changes** (removed or renamed fields, changed behaviour, new required parameters): increment the major version and mount a new `NinjaAPI` instance at the new URL prefix (e.g. `/api/v2/`). The previous major version URL is kept alive for a deprecation period (broadly speaking, until it becomes annoying and pointless to maintain it).
32
32
33
-
#### Option 2: URL-based major versioning with pinned minor version URLs
33
+
The `NinjaAPI(version=...)` string in `core/api.py` is not used as a manually maintained minor version. Deployed version identity is provided by the commit SHA.
34
34
35
-
As Option 1, but also expose pinned minor version URLs (e.g. `/api/v1.1/`) so consumers can opt in to a specific minor version and avoid unexpected changes from non-breaking additions.
35
+
####Option 2: URL-based major versioning with major.minor convention
36
36
37
-
Given there is a single consumer codebase, pinned minor version URLs add URL routing and documentation complexity with no practical benefit — a well-implemented consumer should be tolerant of new optional fields and endpoints.
37
+
As Option 1, but also maintain a `major.minor` version string in the `NinjaAPI` constructor, incremented on every non-breaking change. This was considered but rejected: the minor version string is purely informational, carries no enforcement mechanism beyond code review, and in practice could be forgotten and drift out of sync. The commit SHA already provides reliable deployed-version identity.
38
38
39
-
#### Option 3: Header-based versioning (`Accept` or custom header)
39
+
#### Option 3: URL-based major versioning with pinned minor version URLs
40
+
41
+
As Option 2, but also expose pinned minor version URLs (e.g. `/api/v1.1/`) so consumers can opt in to a specific minor version. Given there is a single consumer codebase, this adds routing and documentation complexity with no practical benefit.
42
+
43
+
#### Option 4: Header-based versioning (`Accept` or custom header)
40
44
41
45
Version communicated via a request header rather than the URL. Less discoverable, harder to test manually, and not the established convention in NHS Digital services.
42
46
43
47
### Outcome
44
48
45
-
Option 1. URL-based major versioning with a `major.minor` convention. This is a reversible decision — if the need for pinned minor version URLs arises (e.g. a second consumer is added), Option 2 can be adopted as a straightforward extension.
49
+
Option 1. URL-based major versioning only. This is a reversible decision — if the need for pinned minor version URLs arises (e.g. a second consumer is added), Option 3 can be adopted as a straightforward extension.
46
50
47
51
### Rationale
48
52
49
-
The URL is the natural and conventional place for an API version. The `major.minor` convention communicates clearly to developers and operators what kind of change has occurred. Pinned minor version URLs (Option 2) are YAGNI given a single consumer codebase.
53
+
The URL is the natural and conventional place for an API version. The major version URL prefix is the only signal that matters for interoperability: it forces an explicit, reviewable decision when a breaking change is introduced. A manually maintained minor version string provides no enforcement and would drift; the commit SHA is a more reliable source of truth for "what is deployed".
50
54
51
55
## Consequences
52
56
53
57
- When a breaking change is made to the API, a new `NinjaAPI` instance must be created in `core/api.py` and mounted at the new version prefix in `core/urls.py`. The previous version must be kept alive until all gateway instances in the field have been updated.
54
-
- Non-breaking changes require only a minor version bump to the `version=` string in the `NinjaAPI` constructor.
55
58
- The deprecation period for an old major version is determined operationally: it should remain available until confidence is high that all deployed gateway instances have been updated. Given hospital IT teams may control update schedules, this window may be longer than a typical SaaS deployment.
56
-
- If a second API consumer is introduced in future, the pinned minor version URL approach (Option 2) should be revisited.
59
+
- If a second API consumer is introduced in future, the pinned minor version URL approach (Option 3) should be revisited.
57
60
58
61
## Compliance
59
62
60
-
Changes to the API should be accompanied by a minor or major version bump as appropriate. Code review is the primary mechanism for enforcing this.
63
+
Breaking API changes must be accompanied by a major version bump (new URL prefix). Code review is the primary enforcement mechanism.
61
64
62
65
## Notes
63
66
64
67
- Current API: `v1`, mounted at `/api/v1/` in `manage_breast_screening/core/urls.py`.
65
-
- Django Ninja `NinjaAPI(version="1.0.0")` in `manage_breast_screening/core/api.py`.
66
-
67
-
## Actions
68
-
69
-
-[ ] Bump the minor version in `NinjaAPI(version=...)` whenever a non-breaking change is made to the API.
68
+
- The `NinjaAPI(version=...)` string in `manage_breast_screening/core/api.py` does not need to be maintained as a minor version.
0 commit comments