Skip to content

Commit 60ab54a

Browse files
committed
Updates bases on last API guidelines working group
- properties and query params must use camel case (updated any references to these in the docs) - updated error handling page
1 parent 82819ad commit 60ab54a

13 files changed

+258
-131
lines changed
Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,93 @@
11
# Data Standards
22

3-
TODO
3+
APIs **SHOULD** follow the GDS Standards
44

5-
- FHIR
6-
- OMOP
5+
## Data Format and Types
6+
7+
- You **SHOULD** define explicit data types for all properties in your OpenAPI schemas.
8+
- You **MUST** ensure that data formats (e.g., date-time, uuid) are used consistently across endpoints.
9+
- You **MAY** introduce custom formats, but they **SHOULD** be documented clearly.
10+
11+
## Data Validation
12+
13+
- You **MUST** validate all incoming request data to maintain consistency and integrity.
14+
- You **SHOULD** apply validation rules at both the service and model levels.
15+
- You **MAY** return validation errors following the problem details guidelines.
16+
17+
## Data Integrity and Consistency
18+
19+
- You **MUST** ensure that data is stored in a reliable manner, preventing partial or corrupted data states.
20+
- You **SHOULD** handle concurrency and conflict scenarios gracefully, especially with multiple updates.
21+
- You **SHOULD NOT** alter data without proper versioning or retention strategies if historical accuracy is required.
22+
23+
## Data Classification and Privacy
24+
25+
- You **MUST** classify sensitive data (PII, PHI, etc.) according to organizational security policies.
26+
- You **SHOULD** mask or encrypt data in transit and at rest, following applicable security guidelines.
27+
- You **MAY** log non-sensitive data for troubleshooting, but **SHOULD NOT** log secrets or personal identifiers.
28+
29+
## Existing Standards
30+
31+
- You **MAY** leverage established data standards and formats, such as [FHIR UK Core](https://digital.nhs.uk/services/fhir-uk-core) and [OMOP](https://www.ohdsi.org/omop/) where appropriate.
32+
- You **SHOULD** document any adaptations to these standards clearly, ensuring consumers understand how they deviate from the official specifications if necessary.
33+
34+
This document outlines best practices for adopting recommended API patterns and data standards within the UKHSA. Adhering to these standards will ensure interoperability, data consistency, and efficient information sharing.
35+
36+
## API Patterns
37+
38+
While the specific API patterns adopted by UKHSA should be clearly defined (e.g., RESTful APIs using JSON), it's crucial to address common errors and their handling. Consistency in error reporting is vital for developers.
39+
The [NHS Spine Core API Framework](https://digital.nhs.uk/services/gp-connect/develop-gp-connect-services/development/error-handling#top) provides a useful model for standardising error handling. While UKHSA's context may differ, a similar approach can be adopted. This involves defining a consistent set of HTTP status codes and associated error messages for various scenarios. Consider mapping specific error conditions to appropriate HTTP status codes (e.g., 400 Bad Request for invalid input, 404 Not Found for missing resources, 500 Internal Server Error for unexpected server issues). Providing detailed error messages in a structured format (e.g., JSON) will aid debugging.
40+
41+
## Data Standards and Record Keeping
42+
43+
The [Professional Record Standards Body (PRSB)](https://theprsb.org/), commissioned by NHS England, plays a vital role in defining data standards for healthcare. Their work, including the [Core Information Standard (CIS)](https://theprsb.org/standards/core-information-standard/), provides a foundation for consistent data recording. CIS defines a set of information elements organised under headings like "Person demographics," covering data points such as `name`, `date of birth`, and `address history`.
44+
45+
Subsets of CIS, like the [Community Pharmacy Standard](https://theprsb.org/standards/communitypharmacy/), tailor the standard to specific healthcare settings. These subsets often share core components with CIS but include additional elements relevant to their specific domain. They may also provide implementation guidance, such as specifying information to be shared with GPs.
46+
47+
While the PRSB standards are valuable, it's important to acknowledge their limitations. Gaps exist, and some terminology may be outdated or contain an excessive number of concepts (e.g., codes for anatomical sites). Other standards, like [OpenEHR](https://specifications.openehr.org/), also exist and should be considered.
48+
49+
UKHSA **SHOULD** evaluate these options and choose the most appropriate standard(s) for their needs.
50+
51+
## Data Model vs. Representation
52+
53+
A crucial distinction exists between a _data model_ (what is stored) and its _representation_ (how it is transmitted). While a data model might mandate storing a citizen's full address history, the Information Commissioner's Office (ICO) Data Protection Principle (c) dictates that only necessary data should be processed for a specific purpose. Sharing a full address history when only a test result is required would be excessive.
54+
55+
Therefore, UKHSA **MUST** carefully consider what data is _stored_ versus what is _sent_. This will vary depending on the use case. Standardising this "what to send" aspect is crucial for efficient and privacy-preserving data exchange.
56+
57+
## FHIR (Fast Healthcare Interoperability Resources)
58+
59+
FHIR, developed by HL7, offers a solution for standardising healthcare data representation and exchange. It addresses:
60+
61+
1. A standard way to represent healthcare concepts in JSON or XML.
62+
2. A standard way to transact this information between systems using FHIR APIs.
63+
64+
FHIR uses "resources" to represent healthcare concepts (e.g., "Medication," "Observation," "Condition," "Patient"). Resources contain elements, which can be primitive data types or complex types defined by the standard. For example, a "Patient" resource includes a `name` element of type `HumanName`, which has specific sub-elements for given names and surname.
65+
66+
_Cardinality_ specifies the number of occurrences of an element. For example, a patient might have multiple given names (cardinality of `0..*` or `1..*`), but typically one surname (`0..1` or `1..1`).
67+
68+
NHS England has developed "[UK Core](https://digital.nhs.uk/services/fhir-uk-core)" FHIR [profiles](https://www.hl7.org/fhir/profiling.html), which are tailored for UK use and align with international profiles (e.g., [US Core](https://www.hl7.org/fhir/us/core/)) where possible. Using profiles ensures consistency and interoperability within the UK.
69+
70+
## Terminology
71+
72+
Terminology (or controlled vocabularies) plays a crucial role in ensuring that data has a consistent and unambiguous meaning. It provides a standardised set of codes and descriptions for concepts, allowing different systems to understand and interpret data correctly. Imagine you're recording information about a person's health. Someone might describe their ailment as a "headache," while another person might describe it as a "migraine." While both relate to head pain, they are distinct conditions. A simple text field might capture both, but it wouldn't allow systems to easily differentiate between them.
73+
74+
Terminology provides specific codes for "headache" and "migraine" (e.g., specific codes within [SNOMED CT](https://digital.nhs.uk/services/terminology-and-classifications/snomed-ct)). Using these standardised codes ensures that all systems understand the precise nature of the reported condition. This is vital for accurate data analysis, reporting, and clinical decision support.
75+
76+
Terminology is _not_ the same as FHIR. FHIR provides the _structure_ and _format_ for exchanging data (like the container), while terminology defines the _meaning_ of the data elements within that structure (like the contents). FHIR resources often reference terminologies to ensure semantic interoperability. For example, a FHIR Observation resource for headache might use SNOMED CT codes to represent the specific type of headache.
77+
78+
Using standardised terminologies (e.g., [SNOMED CT](https://digital.nhs.uk/services/terminology-and-classifications/snomed-ct), [ICD-10](https://classbrowser.nhs.uk/#/book/ICD-10-5TH-Edition)) is essential for data quality, consistency, and interoperability. Within England, the NHS Dictionary of Medicines and Devices (dm+d) is commonly used for medicines and devices. However, it's important to note that other parts of the UK (Scotland, Wales, and Northern Ireland) may use different drug dictionaries and coding systems. Therefore, when exchanging data across the UK, it's crucial to consider these regional variations and ensure appropriate mapping or translation between terminologies.
79+
80+
UKHSA **SHOULD** specify the required terminologies for each data element within their data standards, taking into account these regional differences.
81+
82+
## Additional Considerations
83+
84+
Here are a few more points you might consider adding to the guidance:
85+
86+
- **Versioning:** API patterns, data standards, and terminologies evolve over time. The guidance should address versioning strategies. How will changes be managed? How will backwards compatibility be maintained (or not)? How will consumers of the APIs be notified of changes?
87+
- **Security:** Security is paramount, especially when dealing with sensitive health data. The guidance should include security best practices, such as authentication, authorisation, data encryption (both in transit and at rest), and regular security audits. Reference relevant security standards (e.g., ISO 27001, NIST cybersecurity framework).
88+
- **Data Governance:** Clear data governance policies are essential. Who is responsible for the data? How is data quality ensured? How is data access controlled? How is data retention and disposal managed?
89+
- **Testing:** Robust testing is crucial for ensuring the quality and interoperability of systems. The guidance should encourage thorough testing, including unit tests, integration tests, and performance tests. Consider specifying testing frameworks or tools.
90+
- **Documentation:** Comprehensive documentation is vital for developers and users. APIs and data standards should be well-documented, including clear explanations of their usage, data elements, error codes, and versioning information. Consider using documentation generators (e.g., Swagger/OpenAPI).
91+
- **Implementation Guidance:** Provide practical implementation guidance, including examples and best practices. This will help developers adopt the standards more easily.
92+
- **Conformance Testing:** Consider implementing conformance testing to verify that systems comply with the defined standards. This will help ensure interoperability.
93+
- **Evolution and Maintenance:** The guidance should address how the standards will be maintained and updated over time. Who is responsible for this? What is the process for proposing changes? How will changes be communicated to stakeholders? (edited)

docs/api-design-guidelines/error-handling.md

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ There are some common extension members such as `traceId`, `errors` and `code` w
2424
| `errors` | **MAY** | When you want to respresent multiple validation errors from a single request. |
2525
| `code` | **MAY** | An API specific error code aiding the provider team understand the error based on their own potential taxonomy or registry. |
2626

27+
If an API extends their Problem Details object to include API specific error codes i.e. adding `code` as an extension, then the API specific error codes **MUST** be documented in the OpenAPI definition.
28+
29+
The [MOT history API](https://documentation.history.mot.api.gov.uk/mot-history-api/error-codes/) and [NHS Spine Core API Framework](https://digital.nhs.uk/services/gp-connect/develop-gp-connect-services/development/error-handling#top) provides a useful example for standardising API specific error codes. While UKHSA's context may differ, a similar approach can be adopted while still adhering to [RFC-9457](https://www.rfc-editor.org/rfc/rfc9457.html).
30+
2731
## Common Problems Registry
2832

2933
[RFC-9457](https://www.rfc-editor.org/rfc/rfc9457.html) has the concept of a [registry](https://www.rfc-editor.org/rfc/rfc9457.html#registry) for common problems, given that the intended use for these API Design Guidelines is for an APIM Platform, a **single** shared registry of Problem Details **MAY** be created or an existing registry adopted (as long as there aren't multiple registries) for common responses.
@@ -48,17 +52,40 @@ paths:
4852
$ref: '#/components/schemas/Result'
4953
title: GetResultsListOk
5054
description: A JSON array containing results objects.
51-
'401':
52-
$ref: 'https://developer.ukhsa.gov.uk/openApi/common#/components/responses/Unauthorized'
53-
'403':
54-
$ref: 'https://developer.ukhsa.gov.uk/openApi/common#/components/responses/Forbidden'
55+
'404':
56+
$ref: 'https://developer.ukhsa.gov.uk/openApi/common#/components/responses/NotFound'
57+
default:
58+
$ref: 'https://developer.ukhsa.gov.uk/openApi/common#/#/components/responses/UnexpectedError'
59+
```
60+
61+
``` yaml
62+
# https://developer.ukhsa.gov.uk/openApi/common contents
63+
...
64+
components:
65+
responses:
66+
UnexpectedError:
67+
description: An unexpected error occurred.
68+
content:
69+
application/problem+json:
70+
schema:
71+
$ref: '#/components/schemas/ProblemDetails'
72+
examples:
73+
unauthorized:
74+
$ref: '#/components/examples/unauthorized'
75+
forbidden:
76+
$ref: '#/components/examples/forbidden'
77+
not-found:
78+
$ref: '#/components/examples/not-found'
79+
server-error:
80+
$ref: '#/components/examples/server-error'
81+
...
5582
```
5683

5784
> [!NOTE]
5885
>
59-
> Refer to [RFC-9547](https://www.rfc-editor.org/rfc/rfc9457.html#name-extension-members) standard for additional information.
86+
> Refer to [RFC-9547](https://www.rfc-editor.org/rfc/rfc9457.html) standard for additional information.
6087
61-
## Example Reponses
88+
## Example Responses
6289

6390
### 400 Bad Request - Single Error
6491

docs/api-design-guidelines/naming-conventions.md

Lines changed: 52 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -84,30 +84,24 @@ Avoid:
8484
8585
## Parameter Names
8686
87-
APIs **MUST** use either **snake_case** or **camelCase** consistently and **MUST NOT** mix the two styles.
87+
APIs **MUST** use lower camel case for query parameter names.
8888
8989
Use:
9090
> [!TIP]
91-
> **snake_case**:
92-
>
93-
> ``` text
94-
> /product/v1/users?max_results=10&start_index=20
95-
> ```
96-
>
97-
> **OR camelCase**:
9891
>
9992
> ``` text
10093
> /product/v1/users?maxResults=10&startIndex=20
10194
> ```
10295
103-
Avoid:
96+
Not:
10497
> [!CAUTION]
105-
> **mixed case**:
10698
>
10799
> ``` text
108-
> /product/v1/users?max_results=10&startIndex=20
100+
> /product/v1/users?max_results=10&start_index=20
109101
> ```
110102
103+
### Terminology
104+
111105
APIs **MUST** use consistent names for query parameters having the same function across different endpoints.
112106
113107
Example:
@@ -116,40 +110,63 @@ Example:
116110
>
117111
> ``` text
118112
> /product/v1/orders?limit=10&offset=20
119-
> /product/v1/users?max_results=10&start_index=20
113+
> /product/v1/users?maxResults=10&startIndex=20
120114
> ```
121115
122-
Use consistent terminology across the API and in documentation. For instance, if you use `customer` in one part of your API, don't switch to `client` in another API if they represent the same concept.
116+
## Property Names
117+
118+
APIs **MUST** use lower camel case for properties.
123119
124120
Example:
125121
126-
> [!CAUTION]
122+
Use:
123+
> [!TIP]
127124
>
128-
> ``` text
129-
> /product/v1/orders?customer_id=123
130-
> /product/v1/users?client_id=123
125+
> ``` json
126+
> {
127+
> "customerId": "12345",
128+
> "userId" : "54321"
129+
> }
131130
> ```
132131
133-
## Property Names
134-
135-
APIs **MUST** use either **snake_case** or **camelCase** consistently and **MUST NOT** mix the two styles.
132+
Not:
133+
> [!CAUTION]
134+
>
135+
> ``` json
136+
> {
137+
> "customer_id": "12345",
138+
> "user_id" : "54321"
139+
> }
140+
> ```
136141
137-
For example:
142+
## Terminology
138143
139-
**snake_case**:
144+
Use consistent terminology across the API and in documentation. For instance, if you use `customer` in one part of your API, don't switch to `client` in another API if they represent the same concept.
140145
141-
``` json
142-
{
143-
"customer_id": "12345",
144-
"user_id" : "54321"
145-
}
146-
```
146+
Example query string:
147147
148-
**OR camelCase**:
148+
> [!CAUTION]
149+
>
150+
> ``` text
151+
> /product/v1/orders?customerId=123
152+
> /product/v1/users?clientId=123
153+
> ```
149154
150-
``` json
151-
{
152-
"customerId": "12345",
153-
"userId" : "54321"
154-
}
155-
```
155+
Example request/response model:
156+
> [!CAUTION]
157+
>
158+
> ``` json
159+
> # order
160+
> {
161+
> "orderId": "12345",
162+
> "customerId" : "54321"
163+
> ...
164+
> }
165+
>
166+
> # user
167+
> {
168+
> "userId": "12345",
169+
> "clientId" : "54321"
170+
> ...
171+
> }
172+
> ```

docs/api-design-guidelines/pagination-filtering-sorting.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ The body of responses containing lists of results **SHOULD** contain pagination
4040
// ... more results ...
4141
],
4242
"metadata": {
43-
"total_results": 100,
44-
"total_pages": 10,
45-
"current_page": 1,
46-
"page_size": 10
43+
"totalResults": 100,
44+
"totalPages": 10,
45+
"currentPage": 1,
46+
"pageSize": 10
4747
}
4848
}
4949
```
@@ -151,10 +151,10 @@ paths:
151151
152152
Default sort order **SHOULD** be considered as undefined and non-deterministic.
153153
154-
If a explicit sort order is desired, the query parameter `sort` **SHOULD** be used with the following general syntax: `{field_name}|{asc|desc},{field_name}|{asc|desc}`.
154+
If a explicit sort order is desired, the query parameter `sort` **SHOULD** be used with the following general syntax: `{fieldName}|{asc|desc},{fieldName}|{asc|desc}`.
155155

156156
### Example
157157

158158
``` text
159-
GET /product/v1/results?sort=nhs_number|asc,type|desc
159+
GET /product/v1/results?sort=nhsNumber|asc,type|desc
160160
```

docs/api-design-guidelines/versioning-and-deprecation.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ GET /namespace/product/v1
7272
{
7373
"name": "product",
7474
"version": "1.0.1"
75-
"release_date": "2024-09-17"
75+
"releaseDate": "2024-09-17"
7676
"documentation": "https://developer.ukhsa.gov.uk/namespace/product/v1/docs"
77-
"status": "deprecated"
77+
"releaseNotes": "https://developer.ukhsa.gov.uk/namespace/product/v1/releaseNotes"
7878
}
7979
```
8080
@@ -84,8 +84,14 @@ GET /namespace/product/v1
8484

8585
Non-breaking changes, such as adding optional fields, new endpoints, or improving performance **MUST NOT** increment the version number.
8686

87+
**SHOULD** maintain backwards compatibility where possible.
88+
8789
## Deprecation
8890

8991
**MUST** deprecate old API versions and document API deprecation status
9092

9193
**MUST** document when older API versions will be deprecated and eventually retired in the OpenAPI definition.
94+
95+
## Communication
96+
97+
**SHOULD** notify API consumers of upcoming changes.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# **MUST** use camel case for property names
2+
3+
Property names **MUST** use [camel-case](https://en.wikipedia.org/wiki/Camel_case) strings that match this pattern: `^[a-z][a-z0-9]+(?:[A-Z][a-z0-9]+)*$`.
4+
5+
| Name | Description |
6+
|---------|-------------|
7+
| camel case | The first letter of the first word **MUST** begin with a lowercase letter, the first letter of each subsequent word **MUST** begin with a capital letter and **MUST NOT** contain any separators between words such as spaces or special characters such as hyphens or underscores. |
8+
9+
## Invalid Examples
10+
11+
``` text
12+
CustomerNumber
13+
Customer_Number
14+
customer-number
15+
```
16+
17+
## Valid Examples
18+
19+
``` text
20+
customerNumber
21+
salesOrderNumber
22+
billingAddress
23+
```
24+
25+
[UKHSA Guideline Property Names](../../api-design-guidelines/naming-conventions.md/#property-names)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# **MUST** use camel case for query parameters
2+
3+
Query parameters **MUST** use [camel-case](https://en.wikipedia.org/wiki/Camel_case) strings that match this pattern: `^[a-z][a-z0-9]+(?:[A-Z][a-z0-9]+)*$`.
4+
5+
| Name | Description |
6+
|---------|-------------|
7+
| camel case | The first letter of the first word **MUST** begin with a lowercase letter, the first letter of each subsequent word **MUST** begin with a capital letter and **MUST NOT** contain any separators between words such as spaces or special characters such as hyphens or underscores. |
8+
9+
## Invalid Examples
10+
11+
``` text
12+
/product/v1/users?max_results=10&StartIndex=20&OTHER_PARAM=thing&other_other_param=that
13+
```
14+
15+
## Valid Examples
16+
17+
``` text
18+
/product/v1/users?maxResults=10&startIndex=20
19+
```
20+
21+
[UKHSA Guideline Parameter Names](../../api-design-guidelines/naming-conventions.md/#parameter-names)

0 commit comments

Comments
 (0)