2024-01-21 11:48:28 +00:00
|
|
|
<!doctype html>
|
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<meta charset="utf-8" />
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
|
|
<link
|
|
|
|
rel="stylesheet"
|
|
|
|
href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.5.0/github-markdown.min.css"
|
|
|
|
/>
|
|
|
|
<title>haunt98 posts</title>
|
|
|
|
</head>
|
|
|
|
<style>
|
|
|
|
.markdown-body {
|
|
|
|
box-sizing: border-box;
|
|
|
|
min-width: 200px;
|
|
|
|
max-width: 980px;
|
|
|
|
margin: 0 auto;
|
|
|
|
padding: 45px;
|
|
|
|
}
|
|
|
|
|
|
|
|
@media (max-width: 767px) {
|
|
|
|
.markdown-body {
|
|
|
|
padding: 15px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
<body class="markdown-body">
|
|
|
|
<h2>
|
|
|
|
<a href="index.html"><code>~</code></a>
|
|
|
|
</h2>
|
|
|
|
<h1>
|
|
|
|
<a
|
|
|
|
id="user-content-backend-thinking"
|
|
|
|
class="anchor"
|
|
|
|
aria-hidden="true"
|
|
|
|
tabindex="-1"
|
|
|
|
href="#backend-thinking"
|
|
|
|
><span aria-hidden="true" class="octicon octicon-link"></span></a
|
|
|
|
>Backend Thinking
|
|
|
|
</h1>
|
|
|
|
<h2>
|
|
|
|
<a
|
|
|
|
id="user-content-backend-role"
|
|
|
|
class="anchor"
|
|
|
|
aria-hidden="true"
|
|
|
|
tabindex="-1"
|
|
|
|
href="#backend-role"
|
|
|
|
><span aria-hidden="true" class="octicon octicon-link"></span></a
|
|
|
|
>Backend Role
|
|
|
|
</h2>
|
|
|
|
<p>Transform business requirements to action, which usually involves:</p>
|
|
|
|
<ul>
|
|
|
|
<li>
|
|
|
|
Service:
|
|
|
|
<ul>
|
|
|
|
<li>
|
|
|
|
ZaloPay use microservices architecture, mostly written using Go and
|
|
|
|
Java
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
API:
|
|
|
|
<ul>
|
|
|
|
<li>HTTP (Client-Server) and GRPC (Server-Server)</li>
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
Database/Cache/Storage/Message Broker
|
|
|
|
<ul>
|
|
|
|
<li>MySQL/Redis/S3/Kafka</li>
|
|
|
|
<li>CRUD</li>
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
Docs
|
|
|
|
<ul>
|
|
|
|
<li>
|
|
|
|
Mostly design notes and diagrams which show how to implement
|
|
|
|
business requirements
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
<p>After successfully do all of that, next step is:</p>
|
|
|
|
<ul>
|
|
|
|
<li>
|
|
|
|
Testing
|
|
|
|
<ul>
|
|
|
|
<li>Unit tests, Integration tests</li>
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
Observation
|
|
|
|
<ul>
|
|
|
|
<li>Log</li>
|
|
|
|
<li>Metrics</li>
|
|
|
|
<li>Tracing</li>
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
</ul>
|
2024-01-21 18:41:21 +00:00
|
|
|
<p>
|
|
|
|
In ZaloPay, each team has its own responsibilites/domains, aka many
|
|
|
|
different services.
|
|
|
|
</p>
|
|
|
|
<p>
|
|
|
|
Ideally each team can choose custom backend techstack if they want, but
|
|
|
|
mostly boils down to Java or Go. Some teams use Python for scripting, data
|
|
|
|
processing, ...
|
|
|
|
</p>
|
|
|
|
<p>
|
|
|
|
<em>Example</em>: UM (Team User Management Core) has 10+ Java services and
|
|
|
|
30+ Go services.
|
|
|
|
</p>
|
|
|
|
<p>
|
|
|
|
The question is for each new business requirements, what should we do:
|
|
|
|
</p>
|
|
|
|
<ul>
|
|
|
|
<li>Create new services with new APIs?</li>
|
|
|
|
<li>Add new APIs to existing services?</li>
|
|
|
|
<li>Update existing APIs?</li>
|
|
|
|
<li>Change configs?</li>
|
|
|
|
<li>Don't do anything?</li>
|
|
|
|
</ul>
|
|
|
|
<p>
|
|
|
|
<em>Example</em>: Business requirements says: Must match/compare user EKYC
|
|
|
|
data with Bank data (name, dob, id, ...). TODO
|
|
|
|
</p>
|
|
|
|
<p>TODO: How to split services?</p>
|
|
|
|
<h2>
|
|
|
|
<a
|
|
|
|
id="user-content-technically-side"
|
|
|
|
class="anchor"
|
|
|
|
aria-hidden="true"
|
|
|
|
tabindex="-1"
|
|
|
|
href="#technically-side"
|
|
|
|
><span aria-hidden="true" class="octicon octicon-link"></span></a
|
|
|
|
>Technically side
|
|
|
|
</h2>
|
|
|
|
<p>How do services communicate with each other?</p>
|
|
|
|
<p>
|
|
|
|
<strong>First</strong> is through API, this is the direct way, you send a
|
|
|
|
request then you wait for response.
|
|
|
|
</p>
|
|
|
|
<p><strong>HTTP</strong>: GET/POST/...</p>
|
|
|
|
<p><em>Example</em>: TODO use curl</p>
|
|
|
|
<p><strong>GRPC</strong>: use proto file as constract.</p>
|
|
|
|
<p><em>Example</em>: TODO: show sample proto file</p>
|
|
|
|
<p>
|
|
|
|
There are no hard rules on how to design APIs, only some best practices,
|
|
|
|
like REST API, ...
|
|
|
|
</p>
|
|
|
|
<p>Correct answer will always be: "It depends". Depends on:</p>
|
|
|
|
<ul>
|
|
|
|
<li>
|
|
|
|
Your audience (android, ios, web client or another internal service)
|
|
|
|
</li>
|
|
|
|
<li>Your purpose (allow to do what?)</li>
|
|
|
|
<li>Your current techstack (technology limitation?)</li>
|
|
|
|
<li>Your team (bias, prefer, ...?)</li>
|
|
|
|
<li>...</li>
|
|
|
|
</ul>
|
|
|
|
<p>Why do we use HTTP for Client-Server and GRPC for Server-Server?</p>
|
|
|
|
<ul>
|
|
|
|
<li>
|
|
|
|
HTTP for Client-Server is pretty standard. Easy for client to debug, ...
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
Before ZaloPay switch to GRPC for Server-Server, we use HTTP. The reason
|
|
|
|
for switch is mainly performance.
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
<p>
|
|
|
|
Take a look at
|
|
|
|
<a href="https://stripe.com/docs/api" rel="nofollow">stripe API</a> to get
|
|
|
|
quick grasp about real world API.
|
|
|
|
</p>
|
|
|
|
<p>My own experiences:</p>
|
|
|
|
<ul>
|
|
|
|
<li>
|
|
|
|
Whatever you design, you stick with it consistently. Don't use different
|
|
|
|
name for same object/value in your APIs.
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
Don't trust client blindly, everything can be fake, everything must be
|
|
|
|
validated. We can not know the request is actually from our client or
|
|
|
|
some hacker computer. (Actually we can but this is out of scope, and
|
|
|
|
require lots of advance work)
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
Don't delete/rename/change old fields because you want and you can,
|
|
|
|
please think it through before do it. Because back compability is very
|
|
|
|
hard, old apps should continue to function if user don't upgrade. Even
|
|
|
|
if we rollout new version, it takes time.
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
<h2>
|
|
|
|
<a
|
|
|
|
id="user-content-bonus"
|
|
|
|
class="anchor"
|
|
|
|
aria-hidden="true"
|
|
|
|
tabindex="-1"
|
|
|
|
href="#bonus"
|
|
|
|
><span aria-hidden="true" class="octicon octicon-link"></span></a
|
|
|
|
>Bonus
|
|
|
|
</h2>
|
|
|
|
<p>TODO</p>
|
|
|
|
<h2>
|
|
|
|
<a
|
|
|
|
id="user-content-references"
|
|
|
|
class="anchor"
|
|
|
|
aria-hidden="true"
|
|
|
|
tabindex="-1"
|
|
|
|
href="#references"
|
|
|
|
><span aria-hidden="true" class="octicon octicon-link"></span></a
|
|
|
|
>References
|
|
|
|
</h2>
|
|
|
|
<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>
|
|
|
|
</ul>
|
2024-01-21 11:48:28 +00:00
|
|
|
|
|
|
|
<div>
|
|
|
|
Feel free to ask me via
|
|
|
|
<a href="mailto:hauvipapro+posts@gmail.com">email</a> or
|
|
|
|
<a rel="me" href="https://hachyderm.io/@haunguyen">Mastodon</a>.
|
|
|
|
<br />Source code is available on
|
|
|
|
<a href="https://github.com/haunt98/posts-go">GitHub</a>
|
|
|
|
<a href="https://codeberg.org/yoshie/posts-go">Codeberg</a>
|
|
|
|
<a href="https://git.sr.ht/~youngyoshie/posts-go">sourcehut</a>
|
|
|
|
<a href="https://gitea.treehouse.systems/yoshie/posts-go">Treehouse</a>
|
|
|
|
<a href="https://gitlab.com/youngyoshie/posts-go">GitLab</a>
|
|
|
|
</div>
|
|
|
|
</body>
|
|
|
|
</html>
|