# 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 %}
