# API Specification

Values wrapped in `< >` are placeholders for what the field values should be. Also be sure to read the request route carefully when you implement it.

{% hint style="danger" %}
**NOTE ABOUT ERROR RESPONSES**
{% endhint %}

The server should return an error response for:

* `POST` requests, if the user does not supply one of the fields in the body (e.g. name, username, etc.) with a status code of 400 (bad request)
* `GET` , `POST` and `DELETE` requests, if the requested resource in the URL does not exist, with a status code of 404 (not found)

## Expected Functionality

### Get all users

**`GET`**`/api/users/`

{% code title="Response" %}

```javascript
<HTTP STATUS CODE 200>
{
    "users": [
        {
            "id" 1,
            "name": "Conner",
            "username": "cswenberg",
        },
        {
            "id": 2,
            "name": "Alicia",
            "username": "aawang",
        },
        ...
    ]
}
```

{% endcode %}

{% hint style="danger" %}
Make sure not to include each user’s balance when getting all users - this would be a confidentiality issue in real life!
{% endhint %}

### Create a user

**`POST`**`/api/users/`

{% code title="Request" %}

```javascript
{
    "name": "Raahi Menon",
    "username": "raahi014",
    "balance": <OPTIONAL INTEGER>
}
```

{% endcode %}

{% code title="Response" %}

```javascript
<HTTP STATUS CODE 201>
{
    "id": <ID>
    "name": "Raahi Menon",
    "username": "raahi014",
    "balance": <USER INPUT or DEFAULT TO 0 IF NOT PROVIDED>
}
```

{% endcode %}

{% hint style="warning" %}
If the user does not supply a name, a username, or both, you should return a failure response with a descriptive error message
{% endhint %}

{% hint style="info" %}
You can give a default value of 0 for a key that does not exist for a dictionary like so: `body.get("balance", 0)`
{% endhint %}

### Get a specific user

**`GET`**`/api/user/{id}/`

{% code title="Response" %}

```javascript
<HTTP STATUS CODE 200>
{
    "id": <ID>,
    "name": <STORED NAME FOR USER {id}>,
    "username": <STORED USERNAME FOR USER {id}>,
    "balance": <STORED BALANCE FOR USER {id}>
}
```

{% endcode %}

### Delete a specific user

**`DELETE`**`/api/user/{id}/`

{% code title="Response" %}

```javascript
<HTTP STATUS CODE 200>
{
    "id": <ID>,
    "name": <NAME OF DELETED USER WITH ID {id}>,
    "username": <USERNAME OF DELETED USER WITH ID {id}>,
    "balance": <BALANCE OF DELETED USER WITH ID {id}>
}
```

{% endcode %}

### Send money from one user to another

**`POST`**`/api/send/`

{% code title="Request" %}

```javascript
{
    "sender_id": <USER INPUT>,
    "receiver_id": <USER INPUT>,
    "amount": <USER INPUT>
}
```

{% endcode %}

{% code title="Response" %}

```javascript
<HTTP STATUS CODE 200>
{
    "sender_id": <USER INPUT FOR SENDER>,
    "receiver_id": <USER INPUT FOR RECEIVER>,
    "amount": <USER INPUT FOR AMOUNT> 
}
```

{% endcode %}

{% hint style="warning" %}
A sender should not be able to overdraw their balance! If a request comes in where the sender sends more money than they have, you should return an error with 400 status code.
{% endhint %}

{% hint style="info" %}
If the client does not provide a `sender_id`, `receiver_id`, `amount`, or any combination of those, respond with a descriptive error message and a 400 status code.&#x20;
{% endhint %}

{% hint style="info" %}
When checking if the user actually sent in a `sender_id`, you should check `if sender_id is not None`, instead of `not sender_id`. This is because the number zero is a false-y value, which means `not sender_id` will return `True`, even though the user did supply an `id`, albeit a value of zero. If this is still confusing, consider using `bool()` in a Python shell:

```
>>> bool(None)
False

>>> bool(1)
True

>>> bool(0)
False
```

{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://backend-course.cornellappdev.com/chapters/databases/api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
