Permalink
Browse files

Improved readme

  • Loading branch information...
berndruecker committed Apr 13, 2018
1 parent 1e34f9a commit d564d6b87c66056ecde4abfd17aa1f87a0c2b33d
Showing with 30 additions and 22 deletions.
  1. +15 −5 README.md
  2. +9 −11 rest/README.md
  3. +3 −3 rest/csharp/payment/README.md
  4. +3 −3 rest/java/payment/README.md
@@ -8,6 +8,10 @@ The example respects learnings from **Domain Driven Design (DDD)**, Event Driven
**Note:** The code was written in order to be explained. Hence I favored simplified code or copy & paste over production-ready code with generic solutions. **Don't consider the coding style best practice! It serves the purpose to have easily explainable code**.
Flowing retail simulates a very easy order fulfillment system:
![Events and Commands](docs/workflow-in-service.png)
## Architecture and implemenation alternatives
The most fundamental choice is to select the **communication mechanism**:
@@ -29,19 +33,25 @@ and the **programming language**:
## Storyline
Flowing retail simulates a very easy order fulfillment system. The business logic is separated into the following services (shown as [context map](https://www.infoq.com/articles/ddd-contextmapping)):
Flowing retail simulates a very easy order fulfillment system. The business logic is separated into the services shown above (shown as [context map](https://www.infoq.com/articles/ddd-contextmapping)).
![Microservices](docs/context-map.png)
### Long running services and orchestration
Some services are long running in nature, as e.g. the payment service ask customers to update expired credit cards. Hence a workflow engine is used to persist and control these long running interactions.
Some services are **long running** in nature, as e.g. the payment service ask customers to update expired credit cards. Hence a workflow engine is used to persist and control these long running interactions.
### Workflows live within service boundaries
An important thought is, that this state machine (or workflow engine in this case) is a library used **within** one service. If different services need a workflow engine they potentally run multiple engines. This way it is an autonomous team decision if they want to use some framework and which one:
![Events and Commands](docs/workflow-in-service.png)
Depending on the means of communication (e.g. messaging vs. blocking synchronous REST calls) you also have to tackle quite basic communication problems, e.g. by stateful retries. This is shown in the [REST example](rest/):
### Resilience patterns for synchronous communication
Depending on the means of communication (e.g. messaging vs. blocking synchronous REST calls) you also have to tackle quite basic communication problems, e.g. by stateful retries.
![V1](docs/resilience-patterns/v1.png)
![V1](rest/java/payment/docs/v1.png)
### See [REST example](rest/).
## Links and background reading
@@ -1,33 +1,31 @@
# Flowing Retail / REST
This folder contains services that connect via REST.
Currently this is reduced to:
This folder contains services that connect via REST. Currently this is reduced to showcasing resilience patterns.
# Sample service demonstrating stateful resilience patterns in a REST environment
This sample (micro-)service can retrieve payments and therefor needs to be called via REST. It requires an upstream REST service to charge credit cards.
![REST callstack](docs/situation.png)
![REST callstack](../docs/resilience-patterns/situation.png)
This simple call-chain is great to demonstrate various important resilience patterns.
There are two technology choices available for the code demos:
* [Java, Spring, Hystrix, Camunda](java/payment)
* [.NET Core, C#, Polly, Camunda](csharp/payment)
* [**Java**, Spring, Hystrix, Camunda](java/payment)
* [.NET Core, **C#**, Polly, Camunda](csharp/payment)
# Storyline
* See **Fail fast is not enough**: https://blog.bernd-ruecker.com/fail-fast-is-not-enough-84645d6864d3
See **Fail fast is not enough**: https://blog.bernd-ruecker.com/fail-fast-is-not-enough-84645d6864d3
Assume the credit card service goes nuts, meaning it still responds, but very slow. Having no pattern in place this is the worst thing that can happen - as now the payment service will call the credit card service and block until he gets a response. As this take a long time all threads from the payment service are hold hostile and the payment service will eventually time out for its clients. Tiny failures somewhere in your system might blow up your whole system:
![V1](../docs/resilience-patterns/v1.png)
* Java: [PaymentRestHacksControllerV1.java](java/payment/src/main/java/io/flowing/retail/payment/port/resthacks/PaymentRestHacksControllerV1.java).
* C#: [PaymentControllerV1](csharp/payment/Controllers/PaymentController.cs#L16).
* Java: [PaymentRestHacksControllerV1.java](java/payment/src/main/java/io/flowing/retail/payment/port/resthacks/PaymentRestHacksControllerV1.java)
* C#: [PaymentControllerV1](csharp/payment/Controllers/PaymentController.cs#L16)
## Fail fast
@@ -36,7 +34,7 @@ The least you have to do is to apply a **fail fast** pattern like [**circuit bre
![V2](../docs/resilience-patterns/v2.png)
* Java: [PaymentRestHacksControllerV2.java](java/payment/src/main/java/io/flowing/retail/payment/port/resthacks/PaymentRestHacksControllerV2.java#L41)
* C#: [PaymentControllerV2](csharp/payment/Controllers/PaymentController.cs#L74).
* C#: [PaymentControllerV2](csharp/payment/Controllers/PaymentController.cs#L74)
## Fail fast is not enough
@@ -107,7 +105,7 @@ You have to startup both services:
This varies:
* [How to run in Java](java/payment)
* [How to run in .NET](java/csharp)
* [How to run in .NET](csharp/payment)
Now the different versions of the payment service are available:
@@ -2,13 +2,13 @@
This example demonstrates stateful resilience patterns in a REST environment. A payment (micro-)service can retrieve payments if called via REST. It requires an upstream REST service to charge credit cards.
![REST callstack](docs/situation.png)
![REST callstack](../../docsresilience-patterns/situation.png)
This simple call-chain is great to demonstrate various important resilience patterns.
#See [introduction](../../README.md) for the storyline / patterns behind
# See [introduction](../../README.md) for the storyline / patterns behind
#Concrete technologies/frameworks in this folder:
# Concrete technologies/frameworks in this folder:
* .NET Core 2.0
* C#
@@ -2,13 +2,13 @@
This example demonstrates stateful resilience patterns in a REST environment. A payment (micro-)service can retrieve payments if called via REST. It requires an upstream REST service to charge credit cards.
![REST callstack](docs/situation.png)
![REST callstack](../../docs/resilience-patterns/docs/situation.png)
This simple call-chain is great to demonstrate various important resilience patterns.
#See [introduction](../../README.md) for the storyline / patterns behind
# See [introduction](../../README.md) for the storyline / patterns behind
#Concrete technologies/frameworks in this folder:
# Concrete technologies/frameworks in this folder:
* Java 8
* Spring Boot 1.5.x

0 comments on commit d564d6b

Please sign in to comment.