<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: gamer</title>
    <description>The latest articles on DEV Community by gamer (@sakayaparp).</description>
    <link>https://dev.to/sakayaparp</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F997106%2Fb009eefe-6fd4-4106-87ee-7f5d79d03455.jpeg</url>
      <title>DEV Community: gamer</title>
      <link>https://dev.to/sakayaparp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sakayaparp"/>
    <language>en</language>
    <item>
      <title>Formance from 0 to 0.5</title>
      <dc:creator>gamer</dc:creator>
      <pubDate>Wed, 28 Dec 2022 15:47:54 +0000</pubDate>
      <link>https://dev.to/sakayaparp/formance-from-zero-to-zero-point-five-25p2</link>
      <guid>https://dev.to/sakayaparp/formance-from-zero-to-zero-point-five-25p2</guid>
      <description>&lt;p&gt;&lt;strong&gt;What?&lt;/strong&gt;&lt;br&gt;
Formance Stack เป็น open-source tool ที่ออกแบบมาเพื่อที่จะช่วย developer สร้าง, จัดการ, และติดตามการเข้าออกของเงินในบัญชี โดยเราสามารถนำ tool นี้มีใช้ได้ในโปรเจ็คขนาดเล็ก หรือแม้กระทั่งใน platform ทางการเงินขนาดใหญ่&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Formance Ledger?&lt;/strong&gt;&lt;br&gt;
Formance Ledger คือ service ที่ทำให้เราสามารถติดตามการเคลื่อนไหวหรือ สถานะเกี่ยวกับการเงินได้แบบ real-time และเราสามารถ disign และบันทึก transaction ทางการเงินที่มีความสับซ้อนได้อีกด้วย ซึ่งเราสามารถเขียนโปรแกรมสั่งการได้โดยใช้ Numscript ที่ทำหน้าที่เป็น DSL (domain-specific language) ที่ถูกออกแบบมาช่วยเรา model transaction ทางการเงิน&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hello Formance!!!&lt;/strong&gt;&lt;br&gt;
มาลองใช้ง่ายแบบง่ายๆเพื่อให้เห็นภาพมากขึ้น Formance ได้จัดเตรียมวิธี install service ไว้หลายวิธีแต่วิธีที่ผมเลือกจะใช้ Docker&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 3068:3068 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/numary:/root/.numary &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--env&lt;/span&gt; &lt;span class="nv"&gt;NUMARY_SERVER_HTTP_BIND_ADDRESS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0:3068"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
ghcr.io/formancehq/ledger:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;หรือ Docker compose ซึ่งจะมาพร้อมกับ service postgres ซึ่งเป็น database ที่ใช้แทน default ที่เป็น sqlite&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-L&lt;/span&gt; https://raw.githubusercontent.com/formancehq/ledger/main/docker-compose.yml &lt;span class="nt"&gt;-o&lt;/span&gt; docker-compose.yml

docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ทดสอบโดยการใช้คำสั่ง&lt;/p&gt;

&lt;p&gt;&lt;code&gt;curl -X GET http://127.0.0.1:3068/_info&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hello world!!!&lt;/strong&gt;&lt;br&gt;
ในหัวนี้เราจะเรียนรู้:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;การสร้าง Formance Ledger&lt;/li&gt;
&lt;li&gt;สร้าง models transaction และ account โดยใช้ Numscript&lt;/li&gt;
&lt;li&gt;นำเงินเข้าสู่ระบบด้วย @world account&lt;/li&gt;
&lt;li&gt;ตรวจสอบ transaction และ ยอดคงเหลือใน account&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;อธิบาย @world account เพิ่มเติมที่ต้องมี account นี้เนื่องจากตัว Formance ledger มีการกำหนดว่าเงินที่เข้ามาในระบบไม่สามารถเสกมาจากอากาศลอยๆได้ ดังนั้นจึงต้องมี @world account เพื่อใช้นำเงินจากภายนอกเข้ามาสู่ในระบบ ledger ของเรา &lt;/p&gt;

&lt;p&gt;จากหัวข้อด้านบนตอนนี้เราจะมี service Ledger รันอยู่ในเครื่องแล้ว เราลองมาสร้าง transaction แรกกันด้วยการสร้าง &lt;strong&gt;Numscript&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;first.num&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;send&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;COIN&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;world&lt;/span&gt;
  &lt;span class="nx"&gt;destination&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;centralbank&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="nt"&gt;-Rs&lt;/span&gt; &lt;span class="s1"&gt;'{plain: .}'&lt;/span&gt; first.num &lt;span class="se"&gt;\&lt;/span&gt;
| curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;--data-binary&lt;/span&gt; @- &lt;span class="se"&gt;\&lt;/span&gt;
https://localhost/api/ledger/&lt;span class="o"&gt;{&lt;/span&gt;default&lt;span class="o"&gt;}&lt;/span&gt;/script
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Checking balances&lt;/strong&gt;&lt;br&gt;
ตรวจสอบรายการสามารถทำได้ด้วยการส่งคำสั่ง&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="nt"&gt;--request&lt;/span&gt; GET &lt;span class="s1"&gt;'http://localhost/api/ledger/{quickstart}/aggregate/balances?address=centralbank'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Storage consideration&lt;/strong&gt;&lt;br&gt;
ตัว Formance เองรองรับการเก็บข้อมูลไว้ใน storage 2 อย่างคือ Sqlite และ Postgres ซึ่งโดย default แล้วตัวระบบจะเลือกใช้ Sqlite มาให้ซึ่งสะดวกและง่ายสำหรับการทำการทดสอบบน local แต่ทางระบบเองก็มีการเตือนว่าไม่เหมาะสำหรับการนำมาใช้บน production product และกำลังจะถูก deprecated ใน Formance version 2.X&lt;br&gt;
ตัวเลือกเดียวที่เหมาะสมก็จะเหลือแค่ Postgres ซึ่งเราสามารถใช้งานได้ด้วยการคำหนดค่า Environment&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;NUMARY_STORAGE_DRIVER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;postgres &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nv"&gt;NUMARY_STORAGE_POSTGRES_CONN_STRING&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;postgresql://localhost/dbname &lt;span class="se"&gt;\&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Concurrency Model&lt;/strong&gt;&lt;br&gt;
Formance มีการออกแบบการควบคุม concurrency ของ transaction เพื่อป้องกันการเกิด race condition เป็น 2 ส่วนคือ&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pre-commit in-memory or Redis-based locking&lt;/li&gt;
&lt;li&gt;Optimistic locking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ส่วนการเลือกระหว่าง in-memory or Redis นั่นพิจารณาจากว่าหากเรา deploy แบบ multi-instances ให้เลือกใช้ Redis&lt;br&gt;
&lt;a href="https://docs.formance.com/ledger/reference/concurrency-model"&gt;อ่านเพิ่มเติม&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ledger separation&lt;/strong&gt;&lt;br&gt;
การเลือกแบ่ง Ledger ใน Formance หรือพูดง่ายๆว่าการแบ่ง schema ของ postgres ว่าเราควรจะทำเป็น single ledger หรือ multi-ledger นั่นมีหลักการตัดสิน 2 ข้อคือ&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;หาก application ของเราไม่มีความจำเป็นต้องแชร์ข้อมูลข้าม ledger กันสามารถทำ multi-ledger ได้&lt;/li&gt;
&lt;li&gt;application ที่มี workload ด้าน write สูงและสามารถเก็บข้อมูลแยกกันได้สามารถพิจารณาทำ multi-ledger ได้&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://docs.formance.com/ledger/reference/ledgers"&gt;เพิ่มเติม&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Account&lt;/strong&gt;&lt;br&gt;
เป็นเสมือน container สำหรับ assets เราสามารถส่งและรับ assets ได้ผ่าน transaction โดยผลรวมของ account จะเท่ากับ&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;balance(account)=∑postings(destination)−∑postings(source)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;การตั้งชื่อ account มีการกำหนดว่าต้องตาม เงื่อนไขดังนี้&lt;br&gt;
&lt;code&gt;^[a-zA-Z_0-9]+(:[a-zA-Z_0-9]+){0,}$&lt;/code&gt;&lt;br&gt;
และแนะนำให้ใช้เครื่องหมาย colon ให้การแบ่ง structure เช่น&lt;br&gt;
&lt;code&gt;payments:001:authorizations:001&lt;br&gt;
sales:001:contract&lt;/code&gt;&lt;br&gt;
นอกจากนั้นใน account เรายังสามารถเพิ่มตัว metadata เข้าไปได้ด้วยเพื่อใช้อธิบายรายละเอียดเพิ่มเติมของ account นั่นๆ&lt;br&gt;
&lt;a href="https://docs.formance.com/ledger/reference/accounts"&gt;เพิ่มเติม&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Posting&lt;/strong&gt;&lt;br&gt;
คือการเคลื่อนที่ของจำนวนของ asset จาก account นึงไปยังอีก account นึง เช่น Alice ให้ 100 coins ไปที่ Bob&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bob"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"asset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"COIN"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Transaction&lt;/strong&gt;&lt;br&gt;
ใน Formance transaction คือการ model การรวมกันของ posting ซึ่งเจตนาคือต้องการต้องการทำให้เป็น atomically ตัวอย่างเช่น Alice ใช้ coin ซื้อ gem ผ่าน counter&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"postings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"teller"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"asset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"COIN"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"teller"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"asset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GEM"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://docs.formance.com/ledger/reference/transactions"&gt;เพิ่มเติม&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architecture&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://docs.formance.com/ledger/reference/architecture"&gt;architecture&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Control dashborad&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://docs.formance.com/ledger/operations/using-the-control-dashboard"&gt;control dashborad&lt;/a&gt;&lt;br&gt;
&lt;code&gt;https://control.formance.com/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mastering Numscript&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://docs.formance.com/ledger/numscript/"&gt;coming soon&lt;/a&gt; &lt;br&gt;
&lt;a href="https://docs.formance.com/ledger/numscript/templates/"&gt;numscript template&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Idempotence</title>
      <dc:creator>gamer</dc:creator>
      <pubDate>Tue, 27 Dec 2022 10:07:06 +0000</pubDate>
      <link>https://dev.to/sakayaparp/idempotence-pog</link>
      <guid>https://dev.to/sakayaparp/idempotence-pog</guid>
      <description>&lt;h2&gt;
  
  
  What &amp;amp; Why
&lt;/h2&gt;

&lt;p&gt;ในระบบปัจจุบัน มันยากที่จะระบบใดๆ จะสามารถการันตีการทำงานแบบ exactly once ได้ ฉะนั้นแล้ว service ใดมีโอกาสที่จะเจอปัญหา duplication request/events เข้ามาในระบบได้เสมอ วิธีการที่ practical กว่า คือที่ฝั่ง consumer ของระบบจะต้องทำให้ operation นั้นมีคุณสมบัติเป็น Idempotent กล่าวคือ เมื่อมี duplicate request/event เกิดขึ้น ระบบจะสามารถจัดการกับปัญหาได้โดยไม่สร้าง duplication record หรือ side effect ที่ไม่พึงประสงค์ในระบบ&lt;/p&gt;

&lt;p&gt;วิธีการที่ง่ายที่สุดเพื่อสร้าง Idempotency ให้กับระบบที่ต้องยุ่งกับ database คือพิจารณาว่า เราสามารถทำ upsert กับข้อมูลได้หรือไม่ หรือเราสามารถ ignore ข้อมูลที่ถูกลบไปแล้วได้หรือไม่ เพราะวิธีนี้ เราไม่ต้องจำว่า request ที่เข้ามาใหม่นั้นเคยประมวลผลไปแล้วหรือยัง&lt;/p&gt;

&lt;p&gt;แต่ไม่ใช่ทุกครั้งที่เราจะทำ upsert ได้ ฉะนั้นแล้ว อีกเทคนิคหนึ่งที่ช่วยได้ กล่าวคือ ในฝั่ง consumer จะต้องจดจำ message/request id ที่เคยได้รับมา เมื่อมี message/request id ที่ซ้ำเข้ามาอีก ก็อาจจะเลือก ignore ต่อ operation นั้นไปได้เลย&lt;/p&gt;

&lt;h2&gt;
  
  
  Values &amp;amp; Enablers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;หลีกเลี่ยงปัญหา การทำ operation ใดซ้ำ เมื่อได้รับ message เดิมเข้ามา&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Guidelines
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;พิจารณาใช้เทคนิคนี้เมื่อจำเป็นเท่านั้น เช่นกรณีที่ operation ไม่สามารถทำ upsert ได้ อย่างเช่น การหลีกเลี่ยงการส่ง email ซ้ำๆ เป็นต้น&lt;/li&gt;
&lt;li&gt;เลือกบันทึกเก็บไว้ในฐานข้อมูล ซึ่งทีมอาจจะพิจารณาใช้ Redis หรือ in-memory database ใดๆ เพื่อให้ได้ประสิทธิภาพสูงสุด&lt;/li&gt;
&lt;li&gt;ทีมควรพิจารณาตั้งค่า expiry date ให้กับข้อมูล โดยตั้งเวลาให้เหมาะสมกับเรื่องนั้นๆ เพื่อหลีกเลี่ยงปัญหาข้อมูลบวม&lt;/li&gt;
&lt;li&gt;ให้พิจารณาโอกาสที่ระบบจะถูก replay event ประกอบการตั้งเวลา expiry date ด้วย&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cautions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;หากตั้ง expiry date เร็วเกินไป ก็จะทำให้เกิด duplicate operation ได้อยู่ดี&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://codeopinion.com/handling-duplicate-messages-idempotent-consumers/" rel="noopener noreferrer"&gt;Handling Duplicate Messages (Idempotent Consumers)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://chrisrichardson.net/post/microservices/patterns/2020/10/16/idempotent-consumer.html" rel="noopener noreferrer"&gt;Handling duplicate messages using the Idempotent consumer pattern&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>gratitude</category>
    </item>
    <item>
      <title>Micro frontend</title>
      <dc:creator>gamer</dc:creator>
      <pubDate>Tue, 27 Dec 2022 09:43:28 +0000</pubDate>
      <link>https://dev.to/sakayaparp/micro-frontend-7ma</link>
      <guid>https://dev.to/sakayaparp/micro-frontend-7ma</guid>
      <description>&lt;h2&gt;
  
  
  What &amp;amp; Why
&lt;/h2&gt;

&lt;p&gt;Micro Frontend คือการพัฒนา Frontend โดยการแบ่งย่อยส่วนต่างๆ ให้เล็กลงและแยกจากกัน โดยที่แต่ละส่วนจะเป็นอิสระต่อกันในการพัฒนา, แต่ละส่วนจะสามารถมีทีมของตัวเองรับผิดชอบกับความต้องการทางธุรกิจที่เฉพาะเจาะจงได้&lt;/p&gt;

&lt;p&gt;หาก Application ในปัจจุบันมีโอกาสสูงที่อนาคตจะมีความซับซ้อนมากขึ้นจาก service ที่มี ทำให้ความต้องการ (requirement) ที่ซับซ้อนมากขึ้น การใช้ codebase Frontend ตัวเดียวรับรองทุก business logic อาจจะมีปัญหาตามมาเรื่องความซ้ำซ้อนและและแยกกันไม่ขาดได้ จาก Frontend เช่น&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Map service: ที่ปัจจุบันยังใช้ third party แต่หากในอนาคตจำเป็นต้องพัฒนา service ของตัวเอง ตัว development cycle อาจจะไม่สามารถรวมกันกับ web architecture ปกติได้&lt;/li&gt;
&lt;li&gt;หากว่าในอนาคต service มีมากขึ้น และแต่ละ service มี requirement ของตัวเอง การแบ่งทีมพัฒนาแต่ละส่วน แยก testing, deployment แต่ยังรวมกันเป็น 1 เว็บได้ ถือเป็นเรื่องสำคัญ&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;หน้าตาของ Micro frontend&lt;/p&gt;

&lt;h2&gt;
  
  
  Values &amp;amp; Enablers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;การแยกส่วน frontend component เปรียบได้กับ domain ต่างๆ ซึ่งจะสร้างความคล่องแคล่วในการพัฒนาได้มากขึ้น&lt;/li&gt;
&lt;li&gt;การพัฒนา testing, deployment จะแยกออกจากกัน ทำให้แต่ละทีมทำงานโดยไม่ต้อง depend กับใคร เช่น หาก team a จะใช้ frontend stack ต่างกับ team b ย่อมทำได้&lt;/li&gt;
&lt;li&gt;การพัฒนา platform จะรองรับขนาดทีมที่ใหญ่ขึ้น feature ที่ซับซ้อนขึ้น และการทำงานที่แยกขาดจากกันมากขึ้น&lt;/li&gt;
&lt;li&gt;หากภายใน project Micro Frontend จำเป็นต้อง update version ทั้งของ libary, framework หรือแม้กระทั่งปล่อย release ใหม่ แต่ละ project สามารถทำได้แยกจากกัน และไม่กระทบซึ่งกันและกัน&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Guidelines
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Spike เครื่องมือสำหรับทำ Micro Frontend เช่น &lt;a href="https://piral.io/"&gt;Piral&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;เลือก service ที่มีความเป็น domain ชัดเจน&lt;/li&gt;
&lt;li&gt;แยก Service นั้นออกมาทำ Micro Frontend ผ่านเครื่องมือ (แยก Repo)&lt;/li&gt;
&lt;li&gt;ประมินผลลัพท์และหากเหมาะสม ค่อยเริ่มทะยอยทำ Micro Frontend ภายใน service ต่างๆ โดยดูจากความชัดเจนในตัว domain และผลกระทบต่อ platform&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cautions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ระวังเรื่องการแบ่ง Micro fronend หรือ component หากไม่ได้ออกแบบหรือวางแผนให้ดีก่อนเริ่มทำ อาจทำให้เกิดความซับซ้อนเพิ่มมากขึ้นในระบบ&lt;/li&gt;
&lt;li&gt;ควรมี knowleage และ resource ที่พร้อมเพียงพอก่อนเริ่ม&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Alternatives
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;อาจพิจารณาทำเป็น Monolith แต่ให้คำนึงถึงการออกแบบ component ออกมาให้ให้เป็นสัดส่วนที่ชัดเจน เพื่อที่จะสามารถนำไป reuse ได้ง่าย หรือการที่จะนำไปแบ่งเป็น Micro Frontend ในอนาคต&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://martinfowler.com/articles/micro-frontends.html"&gt;Micro Frontend&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fabrity.com/blog/technical/micro-frontends-pros-and-cons/"&gt;Micro frontends: pros and cons&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mife-demo.florian-rappl.de/products"&gt;Demo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
  </channel>
</rss>
