###### David Westgate
# Rust Axum Question and Answer Server - Backend

## Contents 

I'll do my best to keep these contents up-to-date as changes are made to the source code

* Setup
* Dependency overview
* Source overview
* Looking ahead

### Setup

#### Database
A postgres database is required. At this time, the database must be setup and run manually.

It is convient to run postgres in docker with the postgres:latest docker image. This can be done in a few easy clicks on docker desktop, or as follows with the docker CLI (be sure to pick a POSTGRES_PASSWORD and update [.cargo/config.toml](.cargo/config.toml))
```
docker pull postgres:latest
docker run --name my-postgres-container -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=mypassword -e -p 5432:5432 -d postgres:latest
```

#### Build and Run
```
cd backend
cargo run
```

### Dependency overview

#### std
We utilize std library crates for file input/output, hash maps, and network sockets
#### [Axum](https://crates.io/crates/axum)
Axum is the rust web framework doing much of the heavy lifting of this application. It is used here for its core functionality of routing, and abstracting http concepts like methods, request/response handling, and status codes.
#### [Tokio](https://crates.io/crates/tokio)
The tokio framework allows rust to operate asynchoronously. By axums asychonous web nature, it is required by axum.
#### [Serde/serde_json](https://crates.io/crates/serde)
A useful package for serializing and deserializing data. 
#### [sqlx](https://crates.io/crates/sqlx)
Manages connections and queries to our postgres database 

### Source overview

#### [`src/main.rs`](/backend/src/main.rs)
Our applications main entry point, here we declare the use of the applications external packages for easier management.
`main` is then responsible for creating the new question `store` (behind the necessary tokio `RwLock`). `main` creates the axum router, and specifies all of the routes our application supports by pointing them to handlers in the `src/api.rs` file via the appropriate http methods, before serving the axum service 
#### [`src/api.rs`](/backend/src/api.rs)
Five handlers are defined here for our five API endpoints, supporting the basic CRUD operations regarding questions. Care was taken to handle most common possible error cases, such as attempting to get a question by an id which does not exist, or attempting to create a question with the same ID as one that already exists. 

Some minor derivations were taken here from the exact routes specified in the text
* GET /question/:id is included to return a specific question by id
* GET /questions is programmed to use pagination
* PUT /question does not include the question ID in its path param, but rather just the body
* DELETE /question/:id returns in its body the deleted content
#### [`src/question.rs`](/backend/src/question.rs)
This is the definition of our `struct Question`, `NewQuestion` and `QuestionDTO`.

#### [`src/pg_store.rs`](/backend/src/pg_store.rs)
The store is responsible for the management of the questions, tags, question_tags and answers. It does this by
* Providing public functions to create, retrieve, update or delete questions, create/delete tags, update question_tag associations, and add answers
* Handling possible database interactions errors with some grace

#### [`src/question_tag.rs`](/backend/src/question_tag.rs)

Definition of `QuestionTag` struct
#### [`src/tag.rs`](/backend/src/tag.rs)
Definition of `Tag` struct

#### [`src/answer.rs`](/backend/src/answer.rs)
Definition of `Answer` and `NewAnswer` structs


### Looking ahead
These are a few things still to be added
#### Code cleanup
There is some dept here related to code cleanup I want to address very soon
* Stop using major nested match statements in functions that return options or results. question mark operator should work better for these.
* Deal with some exceptions where I use rust string formatting on query inputs; In some places, this was difficult to avoid.
* Change URL params of ids from u8 to i32 to avoid casting later on.

#### Higher priority
* Add some simple API curl examples to this README
* API documentation tooling (`utoipa`)
* API testing tooling (`swagger`)
* Coded API tests with mock data
* Specific defined Error types for common errors
#### Lesser priority
* Optimize the put/update handler to support path or body identification, and to update only individual fields passed.
* Host application on my raspberry pi on the internet

