The goal was to write a Wallet app where we can store the funds for each user. The Wallet app is responsible to store the funds and provide functionality for manipulating the balance.
The application is using "POST", "DELETE" and "GET" methods for creating, adding, removing funds and queries for the current state of the Wallet. All the data is written to the PostgreSQL database.
I need to get familiar with how the Go programming language is communicating with PostgreSQL so I was using different resources. Resources are listed below in the Useful resources section.
- PostgreSQL database
- Go PostgreSQL driver for handling the database
- Request router for matching incoming requests
- Create, Fetch, and Delete operations
.
├── database
│ ├── db.go
│ └── tables
│ ├── insert.sql
│ └── table.down.sql
├── docker-compose.yml
├── Dockerfile
├── go.mod
├── go.sum
├── main.go
├── models
│ └── model.go
└── README.md
To run the project and tests you will need
- Go Programming language
- Docker
- Docker Compose
- lib/pq - to interact with PostgreSQL
- gorilla/mux - for URL matcher and routing
Build the image and start the Wallet app and PostgreSQL database.
docker-compose up --build
Verify if they are running
docker-compose ps
Output:
Name Command State Ports
--------------------------------------------------------------------------------------------------
wallet /usr/bin/wallet Up 0.0.0.0:8000->8000/tcp,:::8000->8000/tcp
wallet_database docker-entrypoint.sh postgres Up 0.0.0.0:5432->5432/tcp,:::5432->5432/tcp
Connect to the database and add the table.
First, go into the container.
docker exec -it wallet_database /bin/sh
Connect to the database.
psql -U postgres
Add a table.
CREATE TABLE IF NOT EXISTS account(
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
currency VARCHAR(3), /* Currency follows ISO 4217 standard */
balance NUMERIC,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
constraint balance_non_negative check (balance >= 0.0)
);Alternatively, we can use golang-migrate to manage our database migrations.
For graphical user interface Postman can be used, or curl command-line tool in a separate terminal.
curl -X POST '127.0.0.1:8000/wallet/' -d '{"name": "Alice"}'
curl -X POST '127.0.0.1:8000/wallet/deposit/' -d '{"name": "Alice", "balance": 450}'
curl -X POST '127.0.0.1:8000/wallet/withdraw/' -d '{"name": "Alice", "balance": 150}'
curl -X GET '127.0.0.1:8000/wallet/name/' -d '{"name": "Alice"}'
curl -X GET '127.0.0.1:8000/wallet/'
docker-compose stop
All the routes that are exposed in the app.
router.HandleFunc("/wallet/", database.Fetch).Methods("GET")
router.HandleFunc("/wallet/name/", database.FetchByName).Methods("GET")
router.HandleFunc("/wallet/", database.Create).Methods("POST")
router.HandleFunc("/wallet/deposit/", database.Deposit).Methods("POST")
router.HandleFunc("/wallet/withdraw/", database.Withdraw).Methods("POST")
router.HandleFunc("/wallet/delete/", database.DeleteByName).Methods("DELETE")