2021-10-30 21:52:49 +00:00
|
|
|
# API
|
|
|
|
|
|
|
|
Baby Buddy uses the [Django REST Framework](https://www.django-rest-framework.org/)
|
|
|
|
(DRF) to provide a REST API.
|
|
|
|
|
2021-10-31 22:11:07 +00:00
|
|
|
The only requirement for (most) requests is to set the `Authorization` header as
|
|
|
|
described in the [Authentication](#authentication) section. The one exception is
|
|
|
|
the `/api` endpoint, which lists all available endpoints and does not require
|
|
|
|
authorization.
|
2021-10-30 21:52:49 +00:00
|
|
|
|
|
|
|
Currently, the following endpoints are available for `GET`, `OPTIONS`, and
|
|
|
|
`POST` requests:
|
|
|
|
|
2022-05-28 19:46:00 +00:00
|
|
|
- `/api/bmi/` (Body Mass Index)
|
2021-10-30 21:52:49 +00:00
|
|
|
- `/api/children/`
|
|
|
|
- `/api/changes/` (Diaper Changes)
|
|
|
|
- `/api/feedings/`
|
2022-05-28 19:46:00 +00:00
|
|
|
- `/api/head-circumference/`
|
|
|
|
- `/api/height/`
|
2021-10-30 21:52:49 +00:00
|
|
|
- `/api/notes/`
|
2022-05-28 19:46:00 +00:00
|
|
|
- `/api/pumping/`
|
2021-10-30 21:52:49 +00:00
|
|
|
- `/api/sleep/`
|
2022-05-28 19:46:00 +00:00
|
|
|
- `/api/tags/`
|
2021-10-30 21:52:49 +00:00
|
|
|
- `/api/temperature/`
|
|
|
|
- `/api/timers/`
|
|
|
|
- `/api/tummy-times/`
|
|
|
|
- `/api/weight/`
|
|
|
|
|
|
|
|
## Authentication
|
|
|
|
|
2021-10-31 22:11:07 +00:00
|
|
|
The [TokenAuthentication](https://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication)
|
2021-10-30 21:52:49 +00:00
|
|
|
and [SessionAuthentication](https://www.django-rest-framework.org/api-guide/authentication/#sessionauthentication)
|
2021-10-31 22:11:07 +00:00
|
|
|
are enabled by default. Session authentication covers local API requests made by
|
2021-10-30 21:52:49 +00:00
|
|
|
the application itself. Token authentication allows external requests to be
|
|
|
|
made.
|
|
|
|
|
|
|
|
:exclamation: **In a production environment, token authentication should only
|
|
|
|
be used for API calls to an `https` endpoint.** :exclamation:
|
|
|
|
|
2021-10-31 22:11:07 +00:00
|
|
|
Each user has an API key that can be used for token authentication. This key can
|
|
|
|
be found on the User Settings page for the logged in the user. To use a key for
|
|
|
|
an API request, set the request `Authorization` header to `Token <user-key>`. E.g.
|
2021-10-30 21:52:49 +00:00
|
|
|
|
|
|
|
Authorization: Token 2h23807gd72h7hop382p98hd823dw3g665g56
|
|
|
|
|
2021-10-31 22:11:07 +00:00
|
|
|
If no `Authorization` header set, or the key is not valid the API will return
|
|
|
|
`403 Forbidden` with additional details in the response body.
|
2021-10-30 21:52:49 +00:00
|
|
|
|
|
|
|
## Schema
|
|
|
|
|
2021-10-31 22:11:07 +00:00
|
|
|
The API schema in [OpenAPI format](https://swagger.io/specification/) can be
|
2022-02-21 19:29:43 +00:00
|
|
|
found in the [`openapi-schema.yml`](https://github.com/babybuddy/babybuddy/tree/master/openapi-schema.yml)
|
|
|
|
file in the project root. A live version is also available at the `/api/schema` path of
|
|
|
|
a running instance.
|
2021-10-30 21:52:49 +00:00
|
|
|
|
|
|
|
## `GET` Method
|
|
|
|
|
|
|
|
### Request
|
|
|
|
|
|
|
|
The `limit` and `offset` request parameters can be used to limit
|
|
|
|
and offset the results set respectively. For example, the following request
|
|
|
|
will return five diaper changes starting from the 10th diaper change entry:
|
|
|
|
|
2022-05-28 20:47:48 +00:00
|
|
|
```shell
|
|
|
|
curl -X GET 'https://[...]/api/changes/?limit=5&offset=10' -H 'Authorization: Token [...]'
|
|
|
|
```
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
2024-02-07 06:04:17 +00:00
|
|
|
"count": 20,
|
|
|
|
"next": "https://[...]/api/changes/?limit=5&offset=15",
|
|
|
|
"previous": "https://[...]/api/changes/?limit=5&offset=5",
|
|
|
|
"results": []
|
2022-05-28 20:47:48 +00:00
|
|
|
}
|
|
|
|
```
|
2021-10-30 21:52:49 +00:00
|
|
|
|
|
|
|
Field-based filters for specific endpoints can be found the in the `filters`
|
|
|
|
field of the `OPTIONS` response for specific endpoints.
|
|
|
|
|
2024-02-07 06:04:17 +00:00
|
|
|
Single entries can also be retrieved by adding the ID (or in the case of a
|
2021-10-30 21:52:49 +00:00
|
|
|
Child entry, the slug) of a particular entry:
|
|
|
|
|
2022-05-28 20:47:48 +00:00
|
|
|
```shell
|
|
|
|
curl -X GET https://[...]/api/children/gregory-hill/ -H 'Authorization: Token [...]'
|
|
|
|
```
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
2024-02-07 06:04:17 +00:00
|
|
|
"id": 3,
|
|
|
|
"first_name": "Gregory",
|
|
|
|
"last_name": "Hill",
|
|
|
|
"birth_date": "2020-02-11",
|
|
|
|
"slug": "gregory-hill",
|
|
|
|
"picture": null
|
2022-05-28 20:47:48 +00:00
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
```shell
|
|
|
|
curl -X GET https://[...]/api/sleep/1/ -H 'Authorization: Token [...]'
|
|
|
|
```
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
2024-02-07 06:04:17 +00:00
|
|
|
"id": 480,
|
|
|
|
"child": 3,
|
|
|
|
"start": "2020-03-12T21:25:28.916016-07:00",
|
|
|
|
"end": "2020-03-13T01:34:28.916016-07:00",
|
|
|
|
"duration": "04:09:00",
|
|
|
|
"nap": false
|
2022-05-28 20:47:48 +00:00
|
|
|
}
|
|
|
|
```
|
2021-10-30 21:52:49 +00:00
|
|
|
|
|
|
|
### Response
|
|
|
|
|
|
|
|
Returns JSON data in the response body in the following format:
|
|
|
|
|
2022-05-28 20:47:48 +00:00
|
|
|
```json
|
|
|
|
{
|
|
|
|
"count":<int>,
|
|
|
|
"next":<url>,
|
|
|
|
"previous":<url>,
|
|
|
|
"results":[{...}]
|
|
|
|
}
|
|
|
|
```
|
2021-10-30 21:52:49 +00:00
|
|
|
|
2024-02-07 06:04:17 +00:00
|
|
|
- `count`: Total number of records (_in the database_, not just the response).
|
2021-10-30 21:52:49 +00:00
|
|
|
- `next`: URL for the next set of results.
|
|
|
|
- `previous`: URL for the previous set of results.
|
|
|
|
- `results`: An array of the results of the request.
|
|
|
|
|
|
|
|
For single entries, returns JSON data in the response body keyed by model field
|
|
|
|
names. This will vary between models.
|
|
|
|
|
|
|
|
## `OPTIONS` Method
|
|
|
|
|
|
|
|
### Request
|
|
|
|
|
|
|
|
All endpoints will respond to an `OPTIONS` request with detailed information
|
|
|
|
about the endpoint's purpose, parameters, filters, etc.
|
|
|
|
|
|
|
|
### Response
|
|
|
|
|
|
|
|
Returns JSON data in the response body describing the endpoint, available
|
|
|
|
options for `POST` requests, and available filters for `GET` requests. The
|
|
|
|
following example describes the `/api/children` endpoint:
|
|
|
|
|
2022-05-28 20:47:48 +00:00
|
|
|
```json
|
|
|
|
{
|
|
|
|
"name": "Child List",
|
|
|
|
"renders": [
|
|
|
|
"application/json",
|
|
|
|
"text/html"
|
|
|
|
],
|
|
|
|
"parses": [
|
|
|
|
"application/json",
|
|
|
|
"application/x-www-form-urlencoded",
|
|
|
|
"multipart/form-data"
|
|
|
|
],
|
|
|
|
"actions": {
|
|
|
|
"POST": {
|
|
|
|
"id": {
|
|
|
|
"type": "integer",
|
|
|
|
"required": false,
|
|
|
|
"read_only": true,
|
|
|
|
"label": "ID"
|
|
|
|
},
|
|
|
|
[...]
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"filters": [
|
|
|
|
"first_name",
|
|
|
|
"last_name",
|
|
|
|
"slug"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
```
|
2021-10-30 21:52:49 +00:00
|
|
|
|
|
|
|
## `POST` Method
|
|
|
|
|
|
|
|
### Request
|
|
|
|
|
|
|
|
To add new entries for a particular endpoint, send a `POST` request with the
|
|
|
|
entry data in JSON format in the request body. The `Content-Type` header for
|
|
|
|
`POST` request must be set to `application/json`.
|
|
|
|
|
|
|
|
Regular sanity checks will be performed on relevant data. See the `OPTIONS`
|
|
|
|
response for a particular endpoint for details on required fields and data
|
|
|
|
formats.
|
|
|
|
|
|
|
|
### Timer Field
|
|
|
|
|
2022-05-28 20:05:12 +00:00
|
|
|
`POST` requests also accept a `timer` field to model endpoints supporting duration
|
|
|
|
(Feeding, Sleep, Tummy Time). Set `timer` to a valid timer ID in a request instead of
|
|
|
|
the `start` and `end` fields. The new entry will use the `start` and `end` values
|
2024-02-07 06:04:17 +00:00
|
|
|
_from the Timer_ and if the timer is running it will be stopped by this operation.
|
2021-10-30 21:52:49 +00:00
|
|
|
|
2022-05-28 20:05:12 +00:00
|
|
|
Additionally, if the Timer has a child relationship, the `child` field will be
|
|
|
|
filled in automatically with the `child` value from the Timer.
|
2021-10-30 21:52:49 +00:00
|
|
|
|
2022-05-28 20:05:12 +00:00
|
|
|
The `timer` field will **always override** the relevant fields (`child`, `start`,
|
2021-10-31 22:11:07 +00:00
|
|
|
and `end`) on the request. E.g., a `POST` request with both the `timer` and `end`
|
|
|
|
fields will ignore the `end` field value and replace it with the Timer's `end`
|
|
|
|
value. The same applies for `start` and `child`. These fields are all **required**
|
2024-02-07 06:04:17 +00:00
|
|
|
if the `timer` field is _not_ set.
|
2021-10-30 21:52:49 +00:00
|
|
|
|
2022-05-28 20:05:12 +00:00
|
|
|
#### Example `timer` field usage
|
|
|
|
|
|
|
|
Create a new timer associated with a `child`:
|
|
|
|
|
|
|
|
```shell
|
|
|
|
curl --location --request POST '[...]/api/timers/' \
|
|
|
|
--header 'Authorization: Token [...]' \
|
|
|
|
--header 'Content-Type: application/json' \
|
|
|
|
--data-raw '{"child": 1}'
|
|
|
|
```
|
|
|
|
|
|
|
|
Note the timer `id` in the response:
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
2024-02-07 06:04:17 +00:00
|
|
|
"id": 5,
|
|
|
|
"child": 1,
|
|
|
|
"name": null,
|
|
|
|
"start": "2022-05-28T19:59:40.013914Z",
|
|
|
|
"duration": null,
|
|
|
|
"user": 1
|
2022-05-28 20:05:12 +00:00
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
Create a new tummy time entry supplying only the timer `id`:
|
|
|
|
|
|
|
|
```shell
|
|
|
|
curl --location --request POST '[...]/api/tummy-times/' \
|
|
|
|
--header 'Authorization: Token [...]' \
|
|
|
|
--header 'Content-Type: application/json' \
|
|
|
|
--data-raw '{"timer": 5}'
|
|
|
|
```
|
|
|
|
|
|
|
|
Note that `child` and `start` match the timer values (and `end` is auto-populated):
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
2024-02-07 06:04:17 +00:00
|
|
|
"id": 162,
|
|
|
|
"child": 1,
|
|
|
|
"start": "2022-05-28T19:59:40.013914Z",
|
|
|
|
"end": "2022-05-28T20:01:13.549099Z",
|
|
|
|
"duration": "00:01:33.535185",
|
|
|
|
"milestone": "",
|
|
|
|
"tags": []
|
2022-05-28 20:05:12 +00:00
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2022-08-14 20:55:57 +00:00
|
|
|
Also note that the timer has been deleted.
|
2022-05-28 20:05:12 +00:00
|
|
|
|
2021-10-30 21:52:49 +00:00
|
|
|
### Response
|
|
|
|
|
|
|
|
Returns JSON data in the response body describing the added/updated instance or
|
2021-10-31 22:11:07 +00:00
|
|
|
error details keyed by either the field in error or the general string `non_field_errors`
|
|
|
|
(e.g., when validation involves multiple fields).
|
2021-10-30 21:52:49 +00:00
|
|
|
|
|
|
|
## `PATCH` Method
|
|
|
|
|
|
|
|
### Request
|
|
|
|
|
|
|
|
To update existing entries, send a `PATCH` request to the single entry endpoint
|
|
|
|
for the entry to be updated. The `Content-Type` header for `PATCH` request must
|
|
|
|
be set to `application/json`. For example, to update a Diaper Change entry with
|
|
|
|
ID 947 to indicate a "wet" diaper only:
|
|
|
|
|
2022-05-28 20:47:48 +00:00
|
|
|
```shell
|
|
|
|
curl -X PATCH \
|
|
|
|
-H 'Authorization: Token [...]' \
|
|
|
|
-H "Content-Type: application/json" \
|
|
|
|
-d '{"wet":1, "solid":0}' \
|
|
|
|
https://[...]/api/changes/947/
|
|
|
|
```
|
2021-10-30 21:52:49 +00:00
|
|
|
|
|
|
|
Regular sanity checks will be performed on relevant data. See the `OPTIONS`
|
|
|
|
response for a particular endpoint for details on required fields and data
|
|
|
|
formats.
|
|
|
|
|
|
|
|
### Response
|
|
|
|
|
|
|
|
Returns JSON data in the response body describing the added/updated instance or
|
2021-10-31 22:11:07 +00:00
|
|
|
error details keyed by either the field in error or the general string `non_field_errors`
|
|
|
|
(e.g., when validation involves multiple fields).
|
2021-10-30 21:52:49 +00:00
|
|
|
|
|
|
|
## `DELETE` Method
|
|
|
|
|
|
|
|
### Request
|
|
|
|
|
|
|
|
To delete an existing entry, send a `DELETE` request to the single entry
|
|
|
|
endpoint to be deleted. For example, to delete a Diaper Change entry with ID
|
|
|
|
947:
|
|
|
|
|
2022-05-28 20:47:48 +00:00
|
|
|
```shell
|
|
|
|
curl -X DELETE https://[...]/api/changes/947/ -H 'Authorization: Token [...]'
|
|
|
|
```
|
2021-10-30 21:52:49 +00:00
|
|
|
|
|
|
|
### Response
|
|
|
|
|
|
|
|
Returns an empty response with HTTP status code `204` on success, or a JSON
|
|
|
|
encoded error detail if an error occurred (e.g. `{"detail":"Not found."}` if
|
|
|
|
the requested ID does not exist).
|