All Projects → SirWaithaka → simple-wallet

SirWaithaka / simple-wallet

Licence: other
This is a simple wallet REST api that is capable of acount deposits and withdrawals, checking for account balance and providing a ministatement. It follows domain driven design practices. The project uses the DDD architecture approach.

Programming Languages

go
31211 projects - #10 most used programming language
Dockerfile
14818 projects

Projects that are alternatives of or similar to simple-wallet

Goilerplate
Clean Boilerplate of Go, Domain-Driven Design, Clean Architecture, Gin and GORM.
Stars: ✭ 173 (+440.63%)
Mutual labels:  domain-driven-design, clean-architecture, gorm
simple-mpesa
A simple example of how MPESA works. Works with all 3 types of customers i.e. Agents, Merchants and Subscribers. Allows you to configure a tariff and apply it to transactions. The project follows DDD principles.
Stars: ✭ 31 (-3.12%)
Mutual labels:  domain-driven-design, gorm, gofiber
Sample Dotnet Core Cqrs Api
Sample .NET Core REST API CQRS implementation with raw SQL and DDD using Clean Architecture.
Stars: ✭ 1,273 (+3878.13%)
Mutual labels:  domain-driven-design, clean-architecture
Study Path
An organized learning path about Clean Code, Test-Driven Development, Legacy Code, Refactoring, Domain-Driven Design and Microservice Architecture
Stars: ✭ 1,357 (+4140.63%)
Mutual labels:  domain-driven-design, clean-architecture
Domain Driven Hexagon
Guide on Domain-Driven Design, software architecture, design patterns, best practices etc.
Stars: ✭ 4,417 (+13703.13%)
Mutual labels:  domain-driven-design, clean-architecture
clean-architecture
Package for isolate your domain code from framework dependency using DDD concepts.
Stars: ✭ 93 (+190.63%)
Mutual labels:  domain-driven-design, clean-architecture
Practical.cleanarchitecture
Asp.Net Core 5 Clean Architecture (Microservices, Modular Monolith, Monolith) samples (+Blazor, Angular 11, React 17, Vue 2.6), Domain-Driven Design, CQRS, Event Sourcing, SOLID, Asp.Net Core Identity Custom Storage, Identity Server 4 Admin UI, Entity Framework Core, Selenium E2E Testing, SignalR Notification, Hangfire Tasks Scheduling, Health Checks, Security Headers, ...
Stars: ✭ 639 (+1896.88%)
Mutual labels:  domain-driven-design, clean-architecture
Practical Dapr
A full-stack .NET microservices build on Dapr and Tye
Stars: ✭ 140 (+337.5%)
Mutual labels:  domain-driven-design, clean-architecture
Jivejdon
Jivejdon is a Domain Driven Design appication with CQRS/ES/Clean/Hexagonal architecture
Stars: ✭ 287 (+796.88%)
Mutual labels:  domain-driven-design, clean-architecture
Flutter Architecture Ddd
Flutter Architecture inspired by Domain Driven Design, Onion and Clean Architecture
Stars: ✭ 190 (+493.75%)
Mutual labels:  domain-driven-design, clean-architecture
Run Aspnetcore
A starter kit for your next ASP.NET Core web application. Boilerplate for ASP.NET Core reference application, demonstrating a layered application architecture with applying Clean Architecture and DDD best practices. Download 100+ page eBook PDF from here ->
Stars: ✭ 227 (+609.38%)
Mutual labels:  domain-driven-design, clean-architecture
repository
[PHP 7] Implementation and definition of a base Repository in Domain land.
Stars: ✭ 26 (-18.75%)
Mutual labels:  domain-driven-design, clean-architecture
Cp Ddd Framework
A lightweight flexible development framework for complex business architecture with full ecosystem!轻量级业务中台开发框架,中台架构的顶层设计和完整解决方案!
Stars: ✭ 566 (+1668.75%)
Mutual labels:  domain-driven-design, clean-architecture
Event Sourcing Castanha
An Event Sourcing service template with DDD, TDD and SOLID. It has High Cohesion and Loose Coupling, it's a good start for your next Microservice application.
Stars: ✭ 68 (+112.5%)
Mutual labels:  domain-driven-design, clean-architecture
Modular Monolith With Ddd
Full Modular Monolith application with Domain-Driven Design approach.
Stars: ✭ 6,210 (+19306.25%)
Mutual labels:  domain-driven-design, clean-architecture
Polysemycleanarchitecture
Showcasing how the Polysemy library can be used to implement a REST application conforming to the guidelines of the Clean Architecture model.
Stars: ✭ 106 (+231.25%)
Mutual labels:  domain-driven-design, clean-architecture
buchu
Use Cases - Uniform, auditable and secure use case library
Stars: ✭ 23 (-28.12%)
Mutual labels:  domain-driven-design, clean-architecture
CleanArchitecture
ASP.NET Core 6 Web API Clean Architecture Solution Template
Stars: ✭ 312 (+875%)
Mutual labels:  domain-driven-design, clean-architecture
Architecture
.NET 6, ASP.NET Core 6, Entity Framework Core 6, C# 10, Angular 13, Clean Code, SOLID, DDD.
Stars: ✭ 2,285 (+7040.63%)
Mutual labels:  domain-driven-design, clean-architecture
Dotnet New Caju
Learn Clean Architecture with .NET Core 3.0 🔥
Stars: ✭ 228 (+612.5%)
Mutual labels:  domain-driven-design, clean-architecture

Simple Wallet RESTful API

The name of the project is pretty much descriptive enough. To add a little more on the name, the application does the stuff you need from a digital wallet i.e.

  1. Registration and Login
  2. Account Deposit
  3. Account Withdrawal
  4. Balance Enquiry
  5. Mini Statement

PS. This is fully a backend application with no front end client whatsoever. You can use curl, postman or your favourite http tool to interact with the application.

You can follow the below steps to install and setup the application.

Installation

To begin with the application uses postgres as the backend database.

Database Installation

The application uses postgres as the database server. So here are instructions on how to setup postgresql on your machine using docker.

Get the official postgres docker image.

$ docker pull postgres

Then create a container from the image with the following variables

$ docker create \
--name wallet-db \
-e POSTGRES_USER=wallet \
-e POSTGRES_PASSWORD=wallet \
-p 5432:5432 \
postgres

Run the following command to start the container

$ docker start wallet-db

Simple Wallet Installation

Running the application is as simple as running any other go application but first we need to copy and create our configuration.

Lets begin. Cloning ...

$ git clone https://github.com/SirWaithaka/simple-wallet.git

Configuring

$ cd simple-wallet
$ cp config.yml.example config.yml

This configuration file looks something like this

database:
  host: "127.0.0.1"
  port: "5432"
  user: "wallet"
  password: "wallet"
  dbname: "wallet"

app_secret_key: "eQig7GS4cHO2su"

You can change the config variables depending on your database setup, here i choose to follow the default setup shown at database installation step.

Building and running

Using the Binary
$ cd main
$ go build wallet-server.go
$ ./wallet-server

It will install all dependencies required and produce a binary for your platform.

Using the Dockerfile

Make sure you have docker installed and working properly.

$ docker build -t simple-wallet:latest .
$ docker container create --name wallet-server -p 6700:6700 --restart unless-stopped simple-wallet
$ docker container start wallet-server

The server will start at port 6700.

Enjoy.

API

A description of the api.

Endpoints

All the routes exposed in the application are all defined in this function

func apiRouteGroup(g fiber.Router, domain *registry.Domain, config app.Config) {

	g.Post("/login", user_handlers.Authenticate(domain.User, config))
	g.Post("/user", user_handlers.Register(domain.User))

	g.Get("/account/balance", middleware.AuthByBearerToken(config.Secret), account_handlers.BalanceEnquiry(domain.Account))
	g.Post("/account/deposit", middleware.AuthByBearerToken(config.Secret), account_handlers.Deposit(domain.Account))
	g.Post("/account/withdrawal", middleware.AuthByBearerToken(config.Secret), account_handlers.Withdraw(domain.Account))
	g.Post("/account/withdraw", middleware.AuthByBearerToken(config.Secret), account_handlers.Withdraw(domain.Account))

	g.Get("/account/statement", middleware.AuthByBearerToken(config.Secret), account_handlers.MiniStatement(domain.Transaction))
}

The routes are mounted on the prefix /api so your requests should point to

POST /api/login
POST /api/user # for registration
GET /api/account/balance
POST /api/account/deposit
POST /api/account/withdrawal
GET /api/account/statement

To Register

A user can be registered to the api with the following POST parameters firstName, lastName, email, phoneNumber, password

Curl request example

curl --request POST \
  --url http://localhost:6700/api/user \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data firstName=Sir \
  --data lastName=Waithaka \
  --data [email protected] \
  --data phoneNumber=254700000000 \
  --data password=mnbvcxz

Response example

{
    "status": "success",
    "message": "user created",
    "user": {
        "email": "[email protected]",
        "userId": "b4b00501-ba22-49fb-827d-b25d969c58bb"
    }
}

To Login

You can use email and password or phoneNumber and password

Curl request example

curl --request POST \
  --url http://localhost:6700/api/login \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data password=mnbvcxz \
  --data phoneNumber=254700000000

Response example

{
    "userId": "84809a02-9082-4ae3-9047-3840948c57cf",
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7InVzZXJJZCI6Ijg0ODA5YTAyLTkwODItNGFlMy05MDQ3LTM4NDA5NDhjNTdjZiIsImVtYWlsIjoiaGFsbEBlbWFpbC5jb20ifSwiZXhwIjoxNTg0MDI0NTQ0LCJpYXQiOjE1ODQwMDI5NDR9.qZHLJWtYK7_ClgnaPJbGuaiPW8ssd1Ra9xFJWdg6iwE"
}

NOTE: The remaining endpoints require the token acquired above for authentication

To Deposit

You only need the amount parameter

Curl request example

curl --request POST \
  --url http://localhost:6700/api/account/deposit \
  --header 'authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7InVzZXJJZCI6Ijk4YmNmMmY1LWRiY2ItNDk1NS04NTU0LTc0OWYxMTVhZjU5OCIsImVtYWlsIjoiIn0sImV4cCI6MTYwNDA2Mjg0NiwiaWF0IjoxNjA0MDQxMjQ2fQ.Z0oFwOV3wEiQzpwLg4LH5NZIBUsllDhcJefgvceMiHw' \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data amount=1000

Response example

{
  "balance": 1000,
  "message": "Amount successfully deposited new balance 1000",
  "userId": "98bcf2f5-dbcb-4955-8554-749f115af598"
}

To Withdraw

You only need the amount parameter

Curl request example

curl --request POST \
  --url http://localhost:6700/api/account/withdrawal \
  --header 'authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7InVzZXJJZCI6Ijk4YmNmMmY1LWRiY2ItNDk1NS04NTU0LTc0OWYxMTVhZjU5OCIsImVtYWlsIjoiIn0sImV4cCI6MTYwNDA2OTE0MywiaWF0IjoxNjA0MDQ3NTQzfQ.IYyclrC66aweehs_A4Sigmc83a27udmPofM2yOeut9Q' \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data amount=40

Response example

{
  "balance": 880,
  "message": "Amount successfully withdrawn. New balance 880",
  "userId": "98bcf2f5-dbcb-4955-8554-749f115af598"
}

To Query Balance

This is just a GET request, no params

Curl request example

curl --request GET \
  --url http://localhost:6700/api/account/balance \
  --header 'authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7InVzZXJJZCI6Ijk4YmNmMmY1LWRiY2ItNDk1NS04NTU0LTc0OWYxMTVhZjU5OCIsImVtYWlsIjoiIn0sImV4cCI6MTYwNDA2Mjg0NiwiaWF0IjoxNjA0MDQxMjQ2fQ.Z0oFwOV3wEiQzpwLg4LH5NZIBUsllDhcJefgvceMiHw'

Response example

{
    "message": "Your current balance is 4700",
    "balance": 4700
}

To Get Mini Statement

This is just a GET request, no params

Curl request example

curl --request GET \
  --url http://localhost:6700/api/account/statement \
  --header 'authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7InVzZXJJZCI6Ijk4YmNmMmY1LWRiY2ItNDk1NS04NTU0LTc0OWYxMTVhZjU5OCIsImVtYWlsIjoiIn0sImV4cCI6MTYwNDA2OTE0MywiaWF0IjoxNjA0MDQ3NTQzfQ.IYyclrC66aweehs_A4Sigmc83a27udmPofM2yOeut9Q'

Response example

{
    "message": "ministatement retrieved for the past 5 transactions",
    "userId": "84809a02-9082-4ae3-9047-3840948c57cf",
    "transactions": [
        {
            "transactionId": "1088b880-1aa1-4cf0-929b-dfab01c52c13",
            "transactionType": "balance_enquiry",
            "timestamp": "2020-03-12T13:11:09.863693Z",
            "amount": 4700,
            "userId": "84809a02-9082-4ae3-9047-3840948c57cf",
            "accountId": "fd1ce4e4-e467-4eac-8ea0-ea0c9d4f76fe"
        },
        {
            "transactionId": "8b64ca58-b869-47b6-964a-0846957d4c7f",
            "transactionType": "withdrawal",
            "timestamp": "2020-03-12T12:30:37.355034Z",
            "amount": 4700,
            "userId": "84809a02-9082-4ae3-9047-3840948c57cf",
            "accountId": "fd1ce4e4-e467-4eac-8ea0-ea0c9d4f76fe"
        },
        {
            "transactionId": "4514a94c-f303-4324-b010-a4e7c3dd3f77",
            "transactionType": "withdrawal",
            "timestamp": "2020-03-12T12:30:36.278053Z",
            "amount": 4710,
            "userId": "84809a02-9082-4ae3-9047-3840948c57cf",
            "accountId": "fd1ce4e4-e467-4eac-8ea0-ea0c9d4f76fe"
        },
        {
            "transactionId": "871035ad-456a-4467-8260-414b464b6d86",
            "transactionType": "withdrawal",
            "timestamp": "2020-03-12T12:30:35.446227Z",
            "amount": 4720,
            "userId": "84809a02-9082-4ae3-9047-3840948c57cf",
            "accountId": "fd1ce4e4-e467-4eac-8ea0-ea0c9d4f76fe"
        },
        {
            "transactionId": "c3c3a19a-fc3a-4080-9b52-5d3e19853cd7",
            "transactionType": "withdrawal",
            "timestamp": "2020-03-12T12:30:34.646326Z",
            "amount": 4730,
            "userId": "84809a02-9082-4ae3-9047-3840948c57cf",
            "accountId": "fd1ce4e4-e467-4eac-8ea0-ea0c9d4f76fe"
        }
    ]
}

Testing

Tests have not been written for the application but i have very important talks i would share here that i cant recommend enough about how to go about testing the application.

  1. Ian Cooper - TDD, Where Did It All Go Wrong

An approach to testing this application would be something in the following lines.

  1. Test the code in the interactor files
  2. Test the code in the repository files

The above files carry the bulk of the behaviour of the whole application, they are the business logic of the application. The rest of the files are just implementation details that could change rapidly and the tests written for them would certainly fail after change.

e.g. the http handler functions in the application use gofiber, writing unit tests for them is good but not desired, because gofiber can be replaced with mux easily and that would break your tests.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].