feat: draft 3

main
sudo pacman -Syu 2024-01-24 02:48:42 +07:00
parent 1f1a9e2ce8
commit 1be05f3a1f
2 changed files with 181 additions and 58 deletions

View File

@ -190,22 +190,6 @@
><span aria-hidden="true" class="octicon octicon-link"></span></a
>References
</h4>
<ul>
<li>
<a
href="https://stackoverflow.blog/2020/03/02/best-practices-for-rest-api-design/"
rel="nofollow"
>Best practices for REST API design</a
>
</li>
<li>
<a href="https://docs.zalopay.vn/v2/" rel="nofollow">ZaloPay API</a>
</li>
<li>
<a href="https://stripe.com/docs/api" rel="nofollow">stripe API</a>
</li>
<li><a href="https://docs.moov.io/api/" rel="nofollow">moov API</a></li>
</ul>
<h3>
<a
id="user-content-message-broker"
@ -234,26 +218,16 @@
message if they want and do something with it, A does not know and does
not need to know about it.
</p>
<h4>
<h3>
<a
id="user-content-references-1"
id="user-content-tip"
class="anchor"
aria-hidden="true"
tabindex="-1"
href="#references-1"
href="#tip"
><span aria-hidden="true" class="octicon octicon-link"></span></a
>References
</h4>
<ul>
<li>
<a
href="https://blog.cloudflare.com/using-apache-kafka-to-process-1-trillion-messages/"
rel="nofollow"
>Using Apache Kafka to process 1 trillion inter-service messages</a
>
</li>
</ul>
<p>My own experiences:</p>
>Tip
</h3>
<ul>
<li>
Whatever you design, you stick with it consistently. Don't use different
@ -276,6 +250,43 @@
<strong>Pro tip</strong>: Use proto to define models (if you can) to take
advantage of detecting breaking changes.
</p>
<h3>
<a
id="user-content-references-1"
class="anchor"
aria-hidden="true"
tabindex="-1"
href="#references-1"
><span aria-hidden="true" class="octicon octicon-link"></span></a
>References
</h3>
<ul>
<li>
<a
href="https://stackoverflow.blog/2020/03/02/best-practices-for-rest-api-design/"
rel="nofollow"
>Best practices for REST API design</a
>
<ul>
<li>
<a href="https://docs.zalopay.vn/v2/" rel="nofollow">ZaloPay API</a>
</li>
<li>
<a href="https://stripe.com/docs/api" rel="nofollow">stripe API</a>
</li>
<li>
<a href="https://docs.moov.io/api/" rel="nofollow">moov API</a>
</li>
</ul>
</li>
<li>
<a
href="https://blog.cloudflare.com/using-apache-kafka-to-process-1-trillion-messages/"
rel="nofollow"
>Using Apache Kafka to process 1 trillion inter-service messages</a
>
</li>
</ul>
<h2>
<a
id="user-content-coding-principle"
@ -286,6 +297,87 @@
><span aria-hidden="true" class="octicon octicon-link"></span></a
>Coding principle
</h2>
<p>
You should know about DRY, SOLID, KISS, Design Pattern. The basic is
learning which is which when you read code. Truly understand will be
knowing when to use and when to not.
</p>
<p>All of these above are industry standard.</p>
<p>
The way business moving is fast, so a feature is maybe implemented today,
but gets thrown out of window tomorrow (Like A/B testing, one of them is
chosen, the other says bye). So how do we adapt? The problem is to detect,
which code/function is likely stable, resisted changing and which is
likely to change.
</p>
<p>
For each service, I often split to 3 layers: handler, service, repository.
</p>
<ul>
<li>Handler layer: Handle HTTP/GRPC/Message Broker/...</li>
<li>Service layer: All rules, logic goes here.</li>
<li>
Repository layer: Interact with cache/databases using CRUD and some
cache strategy.
</li>
</ul>
<p>
Handler layer is likely never changed. Repository layer is rarely changed.
Service layer is changed daily, this is where I put so much time on.
</p>
<p>The previous question can be asked in many ways:</p>
<ul>
<li>How to move fast without breaking things?</li>
<li>How to quickly experiment new code without affecting old code?</li>
<li>...</li>
</ul>
<p>
My answer is, as Message Broker introduce concept decoupling, loosely
coupled coding. Which means, 2 functions which do not share same business
can be deleted without breaking the other.
</p>
<p>
For example, we can send noti to users using SMS, Zalo, or Noti in app (3
providers). They are all independently feature which serves same purpose:
alert user about something. What happen if we add providers or remove
some? Existing providers keep working as usual, new providers should
behave properly too.
</p>
<p>
So we have send noti abstraction, which can be implement by each provider,
treat like a module (think like lego) which can be plug and play right
away.
</p>
<p>
And when we do not need send noti anymore, we can delete whole of it which
includes all providers and still not affecting main flow.
</p>
<h3>
<a
id="user-content-references-2"
class="anchor"
aria-hidden="true"
tabindex="-1"
href="#references-2"
><span aria-hidden="true" class="octicon octicon-link"></span></a
>References
</h3>
<ul>
<li>
<a
href="https://programmingisterrible.com/post/139222674273/write-code-that-is-easy-to-delete-not-easy-to"
rel="nofollow"
>Write code that is easy to delete, not easy to extend.</a
>
</li>
<li>
<a
href="https://cerebralab.com/Imaginary_Problems_Are_the_Root_of_Bad_Software"
rel="nofollow"
>Imaginary Problems Are the Root of Bad Software</a
>
</li>
</ul>
<h2>
<a
id="user-content-known-concept"
@ -296,7 +388,7 @@
><span aria-hidden="true" class="octicon octicon-link"></span></a
>Known concept
</h2>
<p>TODO:</p>
<p>TODO: Cache strategy, async operation</p>
<h2>
<a
id="user-content-challenge"
@ -330,17 +422,6 @@
>Bonus
</h2>
<p>TODO</p>
<h2>
<a
id="user-content-draft"
class="anchor"
aria-hidden="true"
tabindex="-1"
href="#draft"
><span aria-hidden="true" class="octicon octicon-link"></span></a
>Draft
</h2>
<p>single point of failure ownership, debugging</p>
<div>
Feel free to ask me via

View File

@ -83,11 +83,6 @@ Why do we use HTTP for Client-Server and GRPC for Server-Server?
#### References
- [Best practices for REST API design](https://stackoverflow.blog/2020/03/02/best-practices-for-rest-api-design/)
- [ZaloPay API](https://docs.zalopay.vn/v2/)
- [stripe API](https://stripe.com/docs/api)
- [moov API](https://docs.moov.io/api/)
### Message Broker
**Second** way is by Message Broker, the most well known is Kafka.
@ -106,11 +101,7 @@ Broker, than A forgets about it. Then all B1, B2 can consume A's message if they
want and do something with it, A does not know and does not need to know about
it.
#### References
- [Using Apache Kafka to process 1 trillion inter-service messages](https://blog.cloudflare.com/using-apache-kafka-to-process-1-trillion-messages/)
My own experiences:
### Tip
- Whatever you design, you stick with it consistently. Don't use different name
for same object/value in your APIs.
@ -126,11 +117,66 @@ My own experiences:
**Pro tip**: Use proto to define models (if you can) to take advantage of
detecting breaking changes.
### References
- [Best practices for REST API design](https://stackoverflow.blog/2020/03/02/best-practices-for-rest-api-design/)
- [ZaloPay API](https://docs.zalopay.vn/v2/)
- [stripe API](https://stripe.com/docs/api)
- [moov API](https://docs.moov.io/api/)
- [Using Apache Kafka to process 1 trillion inter-service messages](https://blog.cloudflare.com/using-apache-kafka-to-process-1-trillion-messages/)
## Coding principle
You should know about DRY, SOLID, KISS, Design Pattern. The basic is learning
which is which when you read code. Truly understand will be knowing when to use
and when to not.
All of these above are industry standard.
The way business moving is fast, so a feature is maybe implemented today, but
gets thrown out of window tomorrow (Like A/B testing, one of them is chosen, the
other says bye). So how do we adapt? The problem is to detect, which
code/function is likely stable, resisted changing and which is likely to change.
For each service, I often split to 3 layers: handler, service, repository.
- Handler layer: Handle HTTP/GRPC/Message Broker/...
- Service layer: All rules, logic goes here.
- Repository layer: Interact with cache/databases using CRUD and some cache
strategy.
Handler layer is likely never changed. Repository layer is rarely changed.
Service layer is changed daily, this is where I put so much time on.
The previous question can be asked in many ways:
- How to move fast without breaking things?
- How to quickly experiment new code without affecting old code?
- ...
My answer is, as Message Broker introduce concept decoupling, loosely coupled
coding. Which means, 2 functions which do not share same business can be deleted
without breaking the other.
For example, we can send noti to users using SMS, Zalo, or Noti in app (3
providers). They are all independently feature which serves same purpose: alert
user about something. What happen if we add providers or remove some? Existing
providers keep working as usual, new providers should behave properly too.
So we have send noti abstraction, which can be implement by each provider, treat
like a module (think like lego) which can be plug and play right away.
And when we do not need send noti anymore, we can delete whole of it which
includes all providers and still not affecting main flow.
### References
- [Write code that is easy to delete, not easy to extend.](https://programmingisterrible.com/post/139222674273/write-code-that-is-easy-to-delete-not-easy-to)
- [Imaginary Problems Are the Root of Bad Software](https://cerebralab.com/Imaginary_Problems_Are_the_Root_of_Bad_Software)
## Known concept
TODO:
TODO: Cache strategy, async operation
## Challenge
@ -143,7 +189,3 @@ TODO: Take care incident
## Bonus
TODO
## Draft
single point of failure ownership, debugging