.NET Core with Angular on microservices.
Subscribe for the newest state of products you follow.
- 1. Introduction
- 2. Server Side
- 3. Client Side
- 4. Communication
- 5. RoadMap
- 6. Contributing
- 7. Author
- 8. Inspirations & Thanks
- 9. License
Repository | Master | Develop |
---|---|---|
Ubiquitous | ||
Ubiquitous.Web |
Repositories:
- Notifications
- Channels
- SignalR (WebSocket)
- Push notification (Toastr)
- Types
- Product published, added, changed
- User connected, disconnected
- States
- Trivial, normal, important
- Persistency
- PostgreSQL
- Operations
- Confirmation, hide, remove
- Welcome notifications specified timespan by user preferences
- Channels
- Processing & Capabilities
- Distributed processing number of products paralelly among different adapters
- Identity & Authorization
- Ability to signup, log in, log out, change password
- Identification & auth thanks to jwt token across entire system
- Admin Management (next versions)
- manage products, users, subscriptions
- primarily, self-education has been my motivation, as well as giving my best around topics like
- .NET Core
- DDD
- Microservices
- Docker
- Angular
- and so much more
- Secondly, I wanted to create something solid, from the beginning to the end and that follows newest patterns and good case practices. On the GitHub most of repositories I have ever seen were
- Relatively small, no possibility to run into performance, integration, authorization issues et cetera
- Easy concerns or unfinished
1.3.0. Prerequisites
- Docker
- Docker composer
1.3.1. Run
build-infra.bat
1.3.2. Enter localhost:5450 (PGAdmin) and run
CREATE DATABASE "product-service";
CREATE DATABASE "smartstore-adapter";
CREATE DATABASE "notification-service";
CREATE DATABASE "subscription-service";
CREATE DATABASE "identity-service";
1.3.3 Install services 1.3.3a External run e.g. portainer stack - Replace environment 'ABSOLUTE_PATH' in '.env' file and indicate folder containing configuration - Run > > build-services.external.bat 1.3.3b Local run - Run > build-services.local.bat 1.3.4. Run
docker-compose -f docker-compose-services.yml up
1.3.5. You can manage all containers from portainer dashboard or through Docker CLI.
To be determined
Whole solution is broken down to
- Frontend developed with Angular 7
- Backend developed with .NET Core 3.1.
- Services Functionality-oriented e.g.: products, notifications
- Adapters Encapsulates shops, wholesales logic and enables communication
- Infrastructure, external libraries listed in []
- Solution Files, there can be found anything like GitLab CI manifesto, Docker Compose yml, starting batch files and other solution configurations.
Down below, a services dependency diagram. See to #3.1 for listed used technologies, tools and their use.
What you might see in the scope of my project. Things mentioned below are implemented or used from legal external sources, feel free to use and to contribute.
- RESTful API implemented in ASP.NET Core
- CQRS, Domain-Driven Design, EDA might be found extensively
- Object-Relational Mapping serving easier database connectivity with Entity Framework Core
- AutoMapper & MediatR, thanks to Jimmy Bogard)
- Docker compose (Containers environment)
- Used relational database [PostgreSql] & Cache Redis
- CI & CD defined with Gitlab DevOps
- Docker stacks created with Docker Compose
- API Gateway wtih Ocelot with integrated Service Discovery served by Consul
- Websocket push communication (server to client) with SignalR with Redis backplane
- Polly Resiliency policies
- Message queue RabbitMQ with RawRabbit implementation
- HTTP Calls Load Balancing between services with Fabio
Services
- Product Service Handles products and its business logic
- Background Service Sends periodically queued commands as batch to improve performance
- Notification Service Handles notifications and channels
- Notification Periodic Sender Sends periodically notifications, to improve performance
- Identity Service Handles identity of user and managed Jwt tokens
- Subscription Service Handles subscriptions of users & preferences, bounces integration events
Product Service | Identity Service |
---|---|
Notification Service | Subscription Service |
---|---|
- Generator Service Sources SmartStoreAdapter with fake products
- Fetch Service Sources subscribed ProductService with products related events via RabbitMQ
- SmartStore Adapter Mock Adapter, source of products
Building Blocks
-
Available on Myget version :develop, version :latest
-
U.IntegartionEventLog
- targets .NET Core 3.1
- Module with connectivity to database, storing event for any integration event dispatched
-
U.EventBus
- Abstraction of events
-
U.EventBus.RabbitMQ
- Implementation of EventBus with RabbitMQ
-
Common
- targets NETSTANDARD 2.0
- includes pagination, models shared across projects
-
Common NetCore
- targets .NET Core 3.1
- Metrics - AppMetrics, Influx
- Tracing - OpenTracing, Jaeger
- Logging - Serilog, Elasticsearch
- Service Discovery - Consul
- API Load Balancing - Ocelot
- Service Mesh Load Balancing Fabio
- Retry Policies Polly
- Authentication JWT
- Cache Redis & MemoryCache
Each service is self registering to the Consul registry, containing every active service. This registry as well checks healthness of service with optional keep-alive with specified per-service interval.
Login Page | Dashboard |
---|---|
Subscription | Products |
---|---|
- Entire web app is written in Angular 7 with Angular Material, Bootstrap
- Communication is done with Rx.JS and SignalR
- Charts rendered with ChartistJS
Ubiquitous communicates in two ways, synchronous (HTTP) and asynchronous (WebSocket). These two protocols are used for communication between frontend and backend. Check out the table below explaining differences between them.
Protocol | Communication | Architecture | Server Side Transit | Traffic | Difficulty |
---|---|---|---|---|---|
WebSocket | asynchronous | Push | indirect, through EventBus | Low | High |
HTTP | synchronous | Pull | direct | High | Low |
UI Dashboard statistics are pull-based calls. Each call returns definite data, sourcing charts, either dashboard cards.
On the right, notification bar is websocket-based. Each notification that falls in the bar, is being managed by signalR. You can operate on notifications. Hide, delete or prioritze.
Every command is pushed to the server via web-socket. Any signalr connectivity failure or 401 http call results with loggout and SignalR connection abort.
To be described
Release V0.2 brings
- Heavily extended readme with graphics
- Elasticsearch, Logstash, Kibana
- AppMetrics, Influx
- OpenTracing, Jaeger
- Serilog with Elasticsearch sink
- Routing fixes
- Preferences page fix
Release V.0.3 brings
- Moved major load of determining product's change from PostgreSQL to Redis
- Cache added to Notification Service
- Cache added to Product Service
- Fixed CI/CD Pipelines extensively
- Refactored SmartStoreAdapter
- Identity Service unit tests
Release V.0.4 brings
- Generator Service eligible to modify products in SmartStoreAdapter, then it might generate ProductProperitesChanged and many other events generating in Product Service.
- Nuget versions straightened up, using CI_Pipeline_IID instead of CI_Pipeline_ID. It is an increment value based on project, instead of global number of the pipeline.
- Changed versioning to MAJOR.MINOR.REVISION.BUILD from MAJOR.MINOR.BUILD
- .NET Core 3.1 upgrade
- Performance boost
- UTF8 over Newtonsoft JSON serializers
- Amended Fetch & Generator Services as "Jobs"
- Get rid of Kibana, Logstash
- Get rid of InfluxDB
- Nginx
- Grafana
- Flutter
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Sebastian Rużanowski You can find me at:
- LinkedIn https://www.linkedin.com/in/sebastian-ruzanowski
- GitLab: https://gitlab.com/ruzanowski
- GitHub: https://github.com/sebastianruzanowski
- Repositories
- Sites & Blogs