A simple way to deal with personal finances
This is a proof-of-concept application, which demonstrates Microservice Architecture Pattern using Spring Boot, Spring Cloud and Docker. With a pretty neat user interface, by the way.
PiggyMetrics was decomposed into three core microservices. All of them are independently deployable applications, organized around certain business capability.
Contains general user input logic and validation: incomes/expenses items, savings and account settings.
Method | Path | Description | Authenticated | Available from UI |
---|---|---|---|---|
GET | /accounts/{account} | Get specified account data | ||
GET | /accounts/current | Get current account data | × | × |
GET | /accounts/demo | Get demo account data (pre-filled incomes/expenses items, etc) | × | |
PUT | /accounts/current | Save current account data | × | × |
POST | /accounts/ | Register new account | × |
Performs calculations on major statistics parameters and captures time series for each account. Datapoint contains values, normalized to base currency and time period. This data is used to track cash flow dynamics in account lifetime (fancy charts not yet implemented in UI).
Method | Path | Description | Authenticated | Available from UI |
---|---|---|---|---|
GET | /statistics/{account} | Get specified account statistics | ||
GET | /statistics/current | Get current account statistics | × | × |
GET | /statistics/demo | Get demo account statistics | × | |
PUT | /accounts/{account} | Create or update time series datapoint for specified account |
Stores users contact information and notification settings (like remind and backup frequency). Scheduled worker collects required information from other services and sends e-mail messages to subscribed customers.
Method | Path | Description | Authenticated | Available from UI |
---|---|---|---|---|
GET | /notifications/settings/current | Get current account notification settings | × | × |
PUT | /notifications/settings/current | Save current account notification settings | × | × |
- Each microservice has it's own database, so there is no way to bypass API and access persistance data directly.
- In this project, I use Mongodb as a primary database for each service. It might also make sense to have a polyglot persistence architecture (сhoose the type of db that is best suited to service requirements).
- Service-to-service communication is quite simplified: microservices talking using only synchronous REST API. Common practice in a real-world systems is to use combination of interaction styles. For example, perform synchronous GET request to retrieve data and use asynchronous approach via Message broker for create/update operations in order to decouple services and buffer messages. However, this brings us in eventual consistency world.
There's a bunch of common patterns in distributed systems, which could help us to make described core services work. Spring cloud provides powerful tools that enhance Spring Boot applications behaviour to implement those patterns. I'll cover them briefly.
Spring Cloud Config provides horizontally scalable centralized configuration service in a distributed system. It uses a pluggable repository layer that currently supports local storage, Git, and Subversion.
In this project, I use native profile
, which simply loads config files from the local classpath. You can see shared
directory in Config service resources. Those config files are shared with all applications in cluster. For example, when Statistics-service requests it's configuration, Config service will response with shared/statistics-service.yml
and shared/application.yml
(which is shared between all client applications).
Just build Spring Boot application with spring-cloud-starter-config
. That's it.
You now don't need any embedded properties in your application. Just provide bootstrap.yml
with application name and Config service url:
spring:
application:
name: notification-service
cloud:
config:
uri: http://config:8888
fail-fast: true
For example, EmailService bean was annotated with @RefreshScope
. That means, you can change e-mail text and subject without rebuild and restart Notification service application.
First, change required properties in Config server. Then, perform refresh request to Notification service:
curl -H "Authorization: Bearer #token#" -XPOST http://127.0.0.1:8000/notifications/refresh
Also, you could use Repository webhooks to automate this process
- There are some limitations for dynamic refresh though.
@RefreshScope
doesn't work with@Configuration
classes and doesn't affect@Scheduled
methods fail-fast
property means that Spring Boot application will fail startup immediately, if it cannot connect to the Config Service. That's very useful when we start all applications together- There are significant security notes below
Centralized logging can be very useful when attempting to identify problems in a distributed environment. Elasticsearch, Logstash and Kibana stack lets you search and analyze your logs, utilization and network activity data with ease. Ready-to-go Docker configuration described in my other project.
PiggyMetrics is open source, and would greatly appreciate your help. Feel free to contact me with any questions.