<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>PostgreSQL on Zitao Liao</title><link>http://lzteddy.com/tags/postgresql/</link><description>Recent content in PostgreSQL on Zitao Liao</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Tue, 19 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="http://lzteddy.com/tags/postgresql/index.xml" rel="self" type="application/rss+xml"/><item><title>SUSTech Merch Store Microservices</title><link>http://lzteddy.com/p/sustech-merch-store/</link><pubDate>Wed, 01 Oct 2025 00:00:00 +0000</pubDate><guid>http://lzteddy.com/p/sustech-merch-store/</guid><description>&lt;h2 id="background"&gt;Background
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Time: Oct 2025&lt;/li&gt;
&lt;li&gt;Context: Assignment 2 for SUSTech &amp;ldquo;Distributed and Cloud Computing&amp;rdquo; (module: Services &amp;amp; API Architectures).&lt;/li&gt;
&lt;li&gt;Repository: &lt;a class="link" href="https://github.com/Tsurumalu/SUSTech-Merch-Store" target="_blank" rel="noopener"
 &gt;Tsurumalu/SUSTech-Merch-Store&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="goal"&gt;Goal
&lt;/h2&gt;&lt;p&gt;Build a &lt;strong&gt;microservice-based online merch store&lt;/strong&gt; for SUSTech-branded products. The system exposes RESTful APIs to clients, isolates database access behind a gRPC service, and streams operational logs to Kafka through a dedicated logging service—all orchestrated with Docker Compose.&lt;/p&gt;
&lt;h2 id="architecture"&gt;Architecture
&lt;/h2&gt;&lt;p&gt;Three application services run alongside shared infrastructure:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Service&lt;/th&gt;
 &lt;th&gt;Role&lt;/th&gt;
 &lt;th&gt;Protocol / Stack&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;API Service&lt;/td&gt;
 &lt;td&gt;REST gateway, JWT auth, business orchestration&lt;/td&gt;
 &lt;td&gt;Flask, OpenAPI 3.0&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;DB Service&lt;/td&gt;
 &lt;td&gt;User, product, and order persistence&lt;/td&gt;
 &lt;td&gt;gRPC + psycopg2&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Logging Service&lt;/td&gt;
 &lt;td&gt;Centralized log ingestion&lt;/td&gt;
 &lt;td&gt;gRPC → Kafka&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Infrastructure containers: &lt;strong&gt;PostgreSQL 17&lt;/strong&gt; (persistent storage), &lt;strong&gt;Zookeeper + Kafka&lt;/strong&gt; (log channel &lt;code&gt;log-channel&lt;/code&gt;).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Client ──HTTP──► API Service ──gRPC──► DB Service ──► PostgreSQL
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └──gRPC──► Logging Service ──► Kafka
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="rest-api"&gt;REST API
&lt;/h2&gt;&lt;p&gt;Defined in &lt;code&gt;openapi.yaml&lt;/code&gt; and implemented in Flask:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Dialog:&lt;/strong&gt; &lt;code&gt;GET /&lt;/code&gt; greeting endpoint&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UserManager:&lt;/strong&gt; register, deactivate, get user, update profile, login&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ProductManager:&lt;/strong&gt; list products, get product by ID&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OrderManager:&lt;/strong&gt; place order, cancel order, get order details&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Protected routes use &lt;strong&gt;JWT&lt;/strong&gt; (&lt;code&gt;Bearer&lt;/code&gt; token, HS256, 24-hour expiration). Authentication failures and key operations are forwarded to the logging service.&lt;/p&gt;
&lt;h2 id="data-model"&gt;Data Model
&lt;/h2&gt;&lt;p&gt;PostgreSQL schema (&lt;code&gt;db-init/init.sql&lt;/code&gt;):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;products:&lt;/strong&gt; SUSTech Hoodie, Water Bottle, Notebook (pre-seeded with stock)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;users:&lt;/strong&gt; &lt;code&gt;sid&lt;/code&gt;, username, email, password hash&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;orders:&lt;/strong&gt; user–product linkage with quantity cap (1–3 per order) and computed &lt;code&gt;total_price&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="implementation-highlights"&gt;Implementation Highlights
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Service decomposition:&lt;/strong&gt; API layer never talks to PostgreSQL directly; all DB operations go through the gRPC &lt;code&gt;AssistantService&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Connection pooling:&lt;/strong&gt; DB service uses &lt;code&gt;psycopg2.pool.ThreadedConnectionPool&lt;/code&gt; for concurrent gRPC requests.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Structured logging:&lt;/strong&gt; API service streams &lt;code&gt;LogMessage&lt;/code&gt; events (register, login, order, auth failures) to the logging service, which publishes JSON payloads to Kafka via &lt;code&gt;confluent_kafka&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Containerized deployment:&lt;/strong&gt; &lt;code&gt;compose.yaml&lt;/code&gt; wires &lt;code&gt;api-server&lt;/code&gt;, &lt;code&gt;db-server&lt;/code&gt;, and &lt;code&gt;logging-server&lt;/code&gt; with health-checked Kafka/Zookeeper and volume-backed Postgres init scripts.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dev utilities:&lt;/strong&gt; &lt;code&gt;Makefile&lt;/code&gt; helpers for local &lt;code&gt;psql&lt;/code&gt;, DB reset, and Kafka log streaming.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="tech-stack"&gt;Tech Stack
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Python (Flask, gRPC, PyJWT)&lt;/li&gt;
&lt;li&gt;PostgreSQL 17&lt;/li&gt;
&lt;li&gt;Apache Kafka (Confluent Platform 7.7)&lt;/li&gt;
&lt;li&gt;Docker &amp;amp; Docker Compose&lt;/li&gt;
&lt;li&gt;OpenAPI 3.0&lt;/li&gt;
&lt;li&gt;Protocol Buffers (gRPC service definitions)&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>