fastapi-health
fastapi-health copied to clipboard
Should implement RFC draft for health check
The health check module should implement the RFC draft for health check.
The latest official version of the draft can be found here: https://datatracker.ietf.org/doc/html/draft-inadarei-api-health-check-06
To participate in the development of the draft: https://github.com/inadarei/rfc-healthcheck/
For an example of a Python library that implements the Health Check API: https://github.com/Colin-b/healthpy
I'm going to read the draft later on. Thanks @christianhujer ! :)
1. Add right mime type
Health Check Response Format for HTTP APIs uses the JSON format described in [RFC8259] and has the media type "application/ health+json".
Reference: https://datatracker.ietf.org/doc/html/draft-inadarei-api-health-check-06#section-3
2. Add status field on response
status: (required) indicates whether the service status is acceptable or not. API publishers SHOULD use following values for the field:
- "pass": healthy (acceptable aliases: "ok" to support Node's Terminus and "up" for Java's SpringBoot),
- "fail": unhealthy (acceptable aliases: "error" to support Node's Terminus and "down" for Java's SpringBoot), and
- "warn": healthy, with some concerns.
Should we follow recommendation? Should we allow custom? As it's SHOULD, we probably should allow custom...
Reference: https://datatracker.ietf.org/doc/html/draft-inadarei-api-health-check-06#section-3.1
3. Validate input status
The value of the status field is case-insensitive and is tightly related with the HTTP response code returned by the health endpoint. For "pass" status, HTTP response code in the 2xx-3xx range MUST be used. For "fail" status, HTTP response code in the 4xx-5xx range MUST be used. In case of the "warn" status, endpoints MUST return HTTP status in the 2xx-3xx range, and additional information SHOULD be provided, utilizing optional fields of the response.
We should probably validate the MUSTs here i.e. not allow the user to add 400 on "pass", even if it's obvious.
Reference: https://datatracker.ietf.org/doc/html/draft-inadarei-api-health-check-06#section-3.1
4. Version ?
version: (optional) public version of the service.
Should we use FastAPI(version=...)
here? Even if it's optional, should it really be optional? If yes, should we make the default the FastAPI.version
? I'd say "yes" for the questions here... But allow disabling/using another version.
Reference: https://datatracker.ietf.org/doc/html/draft-inadarei-api-health-check-06#section-3.2
5. Add releaseId
callable
releaseId: (optional) in well-designed APIs, backwards-compatible changes in the service should not update a version number. APIs usually change their version number as infrequently as possible, to preserve stable interface. However, implementation of an API may change much more frequently, which leads to the importance of having separate "release number" or "releaseId" that is different from the public version of the API.
We should probably add a callable to retrieve this value. If callable provided, releaseId
will be on the response, otherwise the field will not be available. If callable result is None
, should we send the releaseId
? I would say yes, to make every response follow the same pattern. But I'm open here.
Reference: https://datatracker.ietf.org/doc/html/draft-inadarei-api-health-check-06#section-3.3
6. Add notes field
notes: (optional) array of notes relevant to current state of health
I need to think about this. Should we give power to the user or have fastapi-health give a summary by itself? Should we have this field at all?
Reference: https://datatracker.ietf.org/doc/html/draft-inadarei-api-health-check-06#section-3.4
7. Add serviceId
serviceId (optional) is a unique identifier of the service, in the application scope.
Add a str
field, if None
, don't provide.
Reference: https://datatracker.ietf.org/doc/html/draft-inadarei-api-health-check-06#section-3.8
8. Add description
description (optional) is a human-friendly description of the service.
Add a str
field, if None
, don't provide.
Reference: https://datatracker.ietf.org/doc/html/draft-inadarei-api-health-check-06#section-3.9
9. Output ?
output: (optional) raw error output, in case of "fail" or "warn" states. This field SHOULD be omitted for "pass" state.
Need to think about it.
Reference: https://datatracker.ietf.org/doc/html/draft-inadarei-api-health-check-06#section-3.5
10. Add checks object
checks (optional) is an object that provides detailed health statuses of additional downstream systems and endpoints which can affect the overall health of the main API. Please refer to the "The Checks Object" section for more information.
Reference:
- https://datatracker.ietf.org/doc/html/draft-inadarei-api-health-check-06#section-3.6
- https://datatracker.ietf.org/doc/html/draft-inadarei-api-health-check-06#section-4
11. Links ?
links (optional) is an object containing link relations and URIs [RFC3986] for external links that MAY contain more information about the health of the endpoint. All values of this object SHALL be URIs. Keys MAY also be URIs. Per web-linking standards [RFC8288] a link relationship SHOULD either be a common/registered one or be indicated as a URI, to avoid name clashes. If a "self" link is provided, it MAY be used by clients to check health via HTTP response code, as mentioned above.
Need to think about it.
Reference: https://datatracker.ietf.org/doc/html/draft-inadarei-api-health-check-06#section-3.7
12. Security concerns
Clients need to exercise care when reporting health information. Malicious actors could use this information for orchestrating attacks. In some cases, the health check endpoints may need to be authenticated and institute role-based access control.
Maybe use a dependency to validate the usage of the endpoint - allowing the client to choose the best authentication method.
Reference: https://datatracker.ietf.org/doc/html/draft-inadarei-api-health-check-06#section-6
13. Cache control ?
Health check responses SHOULD be assigned a freshness lifetime (e.g., "Cache-Control: max-age=3600") so that clients can determine how long they could cache them, to avoid overly frequent fetching and unintended DDOS-ing of the service. Any method of cache lifetime negotiation provided by HTTP spec is acceptable (e.g. ETags are just fine).
Need to think about it.
Reference: https://datatracker.ietf.org/doc/html/draft-inadarei-api-health-check-06#section-9
I'll have to introduce breaking changes to be compliant with the draft, or introduce a new structure to handle the draft.
I'll probably opt for the latter. Add HealthRoute
and a deprecation warning on the health
sounds reasonable. I'd like to maintain the basic usage as simple as possible, but I may have to enforce some output from the condition callables.
Most of the implementation can be found here: https://github.com/Kludex/fastapi-health/pull/11/
I'll finish it tomorrow. Feedback is welcome in the meantime.
EDIT: I didn't finish "tomorrow". I'll see whenever I can.
Any updates on that? Did you manage to finish the implementation as of now?
I'm going to check this week. I have a week off from work. :eyes:
- I've merged #16.
I'll continue to work on it in the following days. I'll need to add a documentation as well.