<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Rpc on Tarragon</title><link>https://tarrragon.github.io/blog/tags/rpc/</link><description>Recent content in Rpc on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Fri, 03 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/rpc/index.xml" rel="self" type="application/rss+xml"/><item><title>11.C23 Echobind：從 GraphQL 撤到 tRPC 的量化帳（反例）</title><link>https://tarrragon.github.io/blog/backend/11-api-design/cases/graphql-echobind-trpc-retreat/</link><pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/11-api-design/cases/graphql-echobind-trpc-retreat/</guid><description>&lt;p>這個案例的核心責任是劃出 GraphQL 與 tRPC 各自的適用邊界、單一 TypeScript 團隊場景的量化對照。跨主題案例：GraphQL 撤退面與 tRPC 採用面共用本檔。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>痛點是 double declaration：同一資料形狀要在 Prisma / Nexus / GraphQL operations / codegen types / client queries 五層宣告；三層 codegen 產出 8,200 行型別檔、常需重啟 VSCode language server；GraphQL 依賴 81.2kb、tRPC 23.7kb；Apollo normalized cache 在 mutation 後常態性要手動 &lt;code>refetchQueries&lt;/code>。遷移後淨減 1,608 行。文章同時明列 tRPC 前提：「server 用 TypeScript 且與 client 共置」、無法有效服務公開第三方 API。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>撤退動因是「單一團隊同時擁有前後端」時、GraphQL 的 schema 中介層變成純開銷 — schema 作為跨團隊 / 跨 client 契約才有價值、同構 TypeScript 單團隊是反指標。作者自列的 tRPC 邊界（公開 API 不適用）可直接引用、避免被讀成萬用推薦。&lt;/p>
&lt;h2 id="對應大綱">對應大綱&lt;/h2>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/backend/11-api-design/styles/graphql/graphql-public-api-tradeoffs/" data-link-title="公開 API 的 GraphQL 進退" data-link-desc="GitHub 雙軌、Shopify all-in、與撤退案例 — 同一技術不同結局的情境變數、GraphQL 的適用邊界">公開 API 的 GraphQL 進退&lt;/a>（適用邊界段、反例、已引用）、styles/rpc-revival/「tRPC 與型別共享」（anchor、backlog）。&lt;/p>
&lt;h2 id="下一步路由">下一步路由&lt;/h2>
&lt;p>回 &lt;a href="https://tarrragon.github.io/blog/backend/11-api-design/cases/" data-link-title="模組十一案例庫：API 設計與對外契約" data-link-desc="API 風格流派、版本與相容、介面語意、規範治理的已驗證公開案例集；含反例與覆蓋缺口標明">模組十一案例庫&lt;/a>。&lt;/p>
&lt;h2 id="引用源">引用源&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://echobind.com/post/why-we-ditched-graphql-for-trpc">Why we ditched GraphQL for tRPC（Echobind blog、2022）&lt;/a>&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>這個案例的核心責任是劃出 GraphQL 與 tRPC 各自的適用邊界、單一 TypeScript 團隊場景的量化對照。跨主題案例：GraphQL 撤退面與 tRPC 採用面共用本檔。</p>
<h2 id="觀察">觀察</h2>
<p>痛點是 double declaration：同一資料形狀要在 Prisma / Nexus / GraphQL operations / codegen types / client queries 五層宣告；三層 codegen 產出 8,200 行型別檔、常需重啟 VSCode language server；GraphQL 依賴 81.2kb、tRPC 23.7kb；Apollo normalized cache 在 mutation 後常態性要手動 <code>refetchQueries</code>。遷移後淨減 1,608 行。文章同時明列 tRPC 前提：「server 用 TypeScript 且與 client 共置」、無法有效服務公開第三方 API。</p>
<h2 id="判讀">判讀</h2>
<p>撤退動因是「單一團隊同時擁有前後端」時、GraphQL 的 schema 中介層變成純開銷 — schema 作為跨團隊 / 跨 client 契約才有價值、同構 TypeScript 單團隊是反指標。作者自列的 tRPC 邊界（公開 API 不適用）可直接引用、避免被讀成萬用推薦。</p>
<h2 id="對應大綱">對應大綱</h2>
<p><a href="/blog/backend/11-api-design/styles/graphql/graphql-public-api-tradeoffs/" data-link-title="公開 API 的 GraphQL 進退" data-link-desc="GitHub 雙軌、Shopify all-in、與撤退案例 — 同一技術不同結局的情境變數、GraphQL 的適用邊界">公開 API 的 GraphQL 進退</a>（適用邊界段、反例、已引用）、styles/rpc-revival/「tRPC 與型別共享」（anchor、backlog）。</p>
<h2 id="下一步路由">下一步路由</h2>
<p>回 <a href="/blog/backend/11-api-design/cases/" data-link-title="模組十一案例庫：API 設計與對外契約" data-link-desc="API 風格流派、版本與相容、介面語意、規範治理的已驗證公開案例集；含反例與覆蓋缺口標明">模組十一案例庫</a>。</p>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://echobind.com/post/why-we-ditched-graphql-for-trpc">Why we ditched GraphQL for tRPC（Echobind blog、2022）</a></li>
</ul>
]]></content:encoded></item><item><title>11.C33 tRPC 設計哲學：無 schema 無 codegen 的型別共享</title><link>https://tarrragon.github.io/blog/backend/11-api-design/cases/rpc-trpc-design-philosophy/</link><pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/11-api-design/cases/rpc-trpc-design-philosophy/</guid><description>&lt;p>這個案例的核心責任是記錄 tRPC 官方自述的設計哲學、含它自己承認的前提與代價。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>核心主張：「build &amp;amp; consume fully typesafe APIs without schemas or code generation」、靠 TypeScript 型別推導、無 codegen、無 runtime bloat、無 build pipeline。官方 FAQ 明言前提與代價：脫離 monorepo 就失去 client 與 server 一起運作的保證、替代方案是把 backend 型別發成 private npm package；動態型別輸出做不到（需 TypeScript 尚未支援的 higher-kinded types）；Netflix、Pleo 等在 production 使用。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>tRPC 是「把 API 契約從 IDL 檔搬進型別系統」的極端點 — 換到零 codegen 的 DX、付出語言鎖定（TS-only）與部署形態鎖定（同倉或私有 npm 包）。教學上與 protobuf 對照：兩者都在解契約同步、一個走 schema-first 跨語言、一個走 inference-first 單語言。&lt;/p>
&lt;h2 id="對應大綱">對應大綱&lt;/h2>
&lt;p>styles/rpc-revival/「tRPC 與型別共享」（anchor、與 C23 Echobind 並用）、11.2 風格選型交叉。&lt;/p>
&lt;h2 id="下一步路由">下一步路由&lt;/h2>
&lt;p>回 &lt;a href="https://tarrragon.github.io/blog/backend/11-api-design/cases/" data-link-title="模組十一案例庫：API 設計與對外契約" data-link-desc="API 風格流派、版本與相容、介面語意、規範治理的已驗證公開案例集；含反例與覆蓋缺口標明">模組十一案例庫&lt;/a>。&lt;/p>
&lt;h2 id="引用源">引用源&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://trpc.io/docs">tRPC docs&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://trpc.io/docs/faq">tRPC FAQ&lt;/a>&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>這個案例的核心責任是記錄 tRPC 官方自述的設計哲學、含它自己承認的前提與代價。</p>
<h2 id="觀察">觀察</h2>
<p>核心主張：「build &amp; consume fully typesafe APIs without schemas or code generation」、靠 TypeScript 型別推導、無 codegen、無 runtime bloat、無 build pipeline。官方 FAQ 明言前提與代價：脫離 monorepo 就失去 client 與 server 一起運作的保證、替代方案是把 backend 型別發成 private npm package；動態型別輸出做不到（需 TypeScript 尚未支援的 higher-kinded types）；Netflix、Pleo 等在 production 使用。</p>
<h2 id="判讀">判讀</h2>
<p>tRPC 是「把 API 契約從 IDL 檔搬進型別系統」的極端點 — 換到零 codegen 的 DX、付出語言鎖定（TS-only）與部署形態鎖定（同倉或私有 npm 包）。教學上與 protobuf 對照：兩者都在解契約同步、一個走 schema-first 跨語言、一個走 inference-first 單語言。</p>
<h2 id="對應大綱">對應大綱</h2>
<p>styles/rpc-revival/「tRPC 與型別共享」（anchor、與 C23 Echobind 並用）、11.2 風格選型交叉。</p>
<h2 id="下一步路由">下一步路由</h2>
<p>回 <a href="/blog/backend/11-api-design/cases/" data-link-title="模組十一案例庫：API 設計與對外契約" data-link-desc="API 風格流派、版本與相容、介面語意、規範治理的已驗證公開案例集；含反例與覆蓋缺口標明">模組十一案例庫</a>。</p>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://trpc.io/docs">tRPC docs</a></li>
<li><a href="https://trpc.io/docs/faq">tRPC FAQ</a></li>
</ul>
]]></content:encoded></item><item><title>11.C34 JSON-RPC 重生：LSP 與 MCP 都選它當訊息層</title><link>https://tarrragon.github.io/blog/backend/11-api-design/cases/rpc-jsonrpc-lsp-mcp-revival/</link><pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/11-api-design/cases/rpc-jsonrpc-lsp-mcp-revival/</guid><description>&lt;p>這個案例的核心責任是記錄 JSON-RPC 重生場景的共同形狀：兩份現代 spec 的採用事實。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>LSP spec 明文 content part 使用 JSON-RPC 描述 requests / responses / notifications、固定 &lt;code>jsonrpc: &amp;quot;2.0&amp;quot;&lt;/code>、外層自訂 Content-Length header 傳輸。MCP spec 規定所有訊息 MUST follow JSON-RPC 2.0、並在其上收緊（request ID 不可為 null、同 session 不可重用）、transport 支援 stdio 與 HTTP、schema 以 TypeScript 為 source of truth。注意：LSP spec 只陳述採用、未寫選型理由段 — 教材推導理由時要標明是判讀、不是引文。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>重生場景的共同形狀：本地 process 間、雙向、低頻、需要 notification 語意、且生態工具（編輯器 / agent）要求零 codegen 可自省 — 這組條件下 gRPC 的 HTTP/2 加 codegen 成本全是負資產。兩份 spec 都「在 JSON-RPC 上加約束」而非發明新協議、是「選最小夠用訊息層」的教材主軸。&lt;/p>
&lt;h2 id="對應大綱">對應大綱&lt;/h2>
&lt;p>styles/rpc-revival/「JSON-RPC 的重生場景」（anchor）、11.2 風格選型交叉。&lt;/p>
&lt;h2 id="下一步路由">下一步路由&lt;/h2>
&lt;p>回 &lt;a href="https://tarrragon.github.io/blog/backend/11-api-design/cases/" data-link-title="模組十一案例庫：API 設計與對外契約" data-link-desc="API 風格流派、版本與相容、介面語意、規範治理的已驗證公開案例集；含反例與覆蓋缺口標明">模組十一案例庫&lt;/a>。&lt;/p>
&lt;h2 id="引用源">引用源&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/">Language Server Protocol Specification 3.17（Microsoft）&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://modelcontextprotocol.io/specification/2025-06-18/basic">Model Context Protocol: Base Protocol（spec、2025-06-18）&lt;/a>&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>這個案例的核心責任是記錄 JSON-RPC 重生場景的共同形狀：兩份現代 spec 的採用事實。</p>
<h2 id="觀察">觀察</h2>
<p>LSP spec 明文 content part 使用 JSON-RPC 描述 requests / responses / notifications、固定 <code>jsonrpc: &quot;2.0&quot;</code>、外層自訂 Content-Length header 傳輸。MCP spec 規定所有訊息 MUST follow JSON-RPC 2.0、並在其上收緊（request ID 不可為 null、同 session 不可重用）、transport 支援 stdio 與 HTTP、schema 以 TypeScript 為 source of truth。注意：LSP spec 只陳述採用、未寫選型理由段 — 教材推導理由時要標明是判讀、不是引文。</p>
<h2 id="判讀">判讀</h2>
<p>重生場景的共同形狀：本地 process 間、雙向、低頻、需要 notification 語意、且生態工具（編輯器 / agent）要求零 codegen 可自省 — 這組條件下 gRPC 的 HTTP/2 加 codegen 成本全是負資產。兩份 spec 都「在 JSON-RPC 上加約束」而非發明新協議、是「選最小夠用訊息層」的教材主軸。</p>
<h2 id="對應大綱">對應大綱</h2>
<p>styles/rpc-revival/「JSON-RPC 的重生場景」（anchor）、11.2 風格選型交叉。</p>
<h2 id="下一步路由">下一步路由</h2>
<p>回 <a href="/blog/backend/11-api-design/cases/" data-link-title="模組十一案例庫：API 設計與對外契約" data-link-desc="API 風格流派、版本與相容、介面語意、規範治理的已驗證公開案例集；含反例與覆蓋缺口標明">模組十一案例庫</a>。</p>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/">Language Server Protocol Specification 3.17（Microsoft）</a></li>
<li><a href="https://modelcontextprotocol.io/specification/2025-06-18/basic">Model Context Protocol: Base Protocol（spec、2025-06-18）</a></li>
</ul>
]]></content:encoded></item></channel></rss>