GithubHelp home page GithubHelp logo

robertohuertasm / payments-engine Goto Github PK

View Code? Open in Web Editor NEW
1.0 2.0 0.0 117 KB

๐Ÿ’ฑ ๐Ÿฆ€ Simple payment engine to process csv transactions

Rust 100.00%
payments cli csv transactions

payments-engine's Introduction

Payments Engine

This project showcases a simple payments engine made with Rust that processes transactions and offers information about the current balance of the accounts.

How to run the CLI

The payments-engine-cli binary reads a CSV file with transactions and outputs the current balance of each account to the std out.

If you want to run it, you can use the following command:

cargo run -- transactions.csv
# or this, if you want to get that info piped into a file
cargo run -- transactions.csv > accounts.csv

Note that there's already a transactons.csv file in the repository if you're curious about the kind of input you should be using.

You should get something similar to this as a response:

client,available,held,total,locked
2,0,0,0,true
1,250.0001,0,250.0001,false

Architecture

The project is separated in several crates.

There are several reasons for that:

  1. Making the compilation faster while developing.
  2. Making the project more modular.
  3. Helping the project to be more maintainable and extensible.
  4. Making it easy to split responsibilities and avoid unwanted coupling.

The idea was to provide a clean architecture.

In order to do that, we defined a Domain layer exposing domain entities and some core traits to be implemented in the other layers.

Basically, we have a Store trait which is responsible for persistence and a Engine trait which is responsible for the business logic.

The current implementation just exposes an In-Memory store and a simple Engine according to some specific business rules but, as we have everything decoupled, we could easily extend this project to provide different kinds of stores (PosgreSQL, Redis, even a REST API, etc.) and different kinds of engines with some particular logic.

At the same time, we're using an async CSV reader/writer to input and output the information but this could be easily changed to any other kind of data source for the same reasons stated above.

Find below a Component Diagram illustrating the architecture.

Architecture

Async

The project makes extense uses of futures to avoid blocking scenarios as much as possible and although it uses Tokio for testing purposes, it's not required in order to implement the Store or the Engine traits, so you could potentially use async-std instead.

Indeed, Tokio it's only a hard dependency in the cli crate and the csv reader/writer crate.

One of the ideas was to provide a feature for at least the csv reader/writer crate to be able to use some other async runtime but I kept it out of the scope for the time being.

On the other hand, we're also using async-trait to simplify dealing with traits and futures.

Testing

All the different components have their own tests to make sure they work as expected.

I put special emphasis on the payments-engine crate, as this is the crate holding all the business logic, but all of them are pretty well covered.

Precisely, given that testing was an important part of this project, leveraging traits in order to avoid implementation coupling helped a lot.

Observability

All the libraries used in this project are using tracing to provide observability.

The cli has a subscriber that will output all the traces to the std out if the RUST_LOG env var is set.

You can either set it yourself or add an .env file to your project with the following content, as we're leveraging the dotenv crate to read the .env file and set the RUST_LOG env var.

RUST_LOG=debug

Error handling

The project uses the usual suspects when dealing with errors:

  • thiserror: to easily create custom Error types.
  • anyhow: for easily handling errors in the CLI.

Generally speaking, both in the libraries and in the cli binary, all the errors are being traced.

That being said, according to the specs, the CLI ignores the serde errors and processing errors from the Engine. It only panics in case there's an error while writing the output.

Other considerations

  • In order to keep the decimal precision up to four places past the decimal and avoid possible rounding issues I decided to use the rust_decimal crate.
  • I tried to favour static vs dynamic dispatch as much as possible where it made sense.
  • The different crates are comprehensively documented in order to help both end-users and developers alike. This improves maintainability and helps people to reason about different functions and design decisions.
  • I used several tools while developing like clippy, cargo-make and cargo-watch.
  • The order of the rows in the output CSV file is not guaranteed.

payments-engine's People

Contributors

robertohuertasm avatar

Stargazers

Andrew Johnson avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.