<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Api on David Lang</title>
    <link>https://www.davidlang.tech/tags/api/</link>
    <description>Recent content in Api on David Lang</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Fri, 05 Sep 2025 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://www.davidlang.tech/tags/api/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>FastAPI &#43; LangChain: Building Production-Ready AI APIs</title>
      <link>https://www.davidlang.tech/posts/fastapi-langchain-building-production-ready-ai-apis/</link>
      <pubDate>Fri, 05 Sep 2025 00:00:00 +0000</pubDate>
      <guid>https://www.davidlang.tech/posts/fastapi-langchain-building-production-ready-ai-apis/</guid>
      <description>&lt;p&gt;FastAPI&amp;rsquo;s async support and automatic OpenAPI docs pair naturally with LangChain for production AI backends.&lt;/p&gt;&#xA;&lt;h2 id=&#34;project-structure&#34;&gt;Project Structure&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;app/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  main.py&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  routers/chat.py&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  services/rag.py&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  models/schemas.py&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;async-endpoint&#34;&gt;Async Endpoint&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#719e07&#34;&gt;from&lt;/span&gt; fastapi &lt;span style=&#34;color:#719e07&#34;&gt;import&lt;/span&gt; FastAPI&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#719e07&#34;&gt;from&lt;/span&gt; pydantic &lt;span style=&#34;color:#719e07&#34;&gt;import&lt;/span&gt; BaseModel&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;app &lt;span style=&#34;color:#719e07&#34;&gt;=&lt;/span&gt; FastAPI()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#719e07&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#268bd2&#34;&gt;ChatRequest&lt;/span&gt;(BaseModel):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    message: &lt;span style=&#34;color:#b58900&#34;&gt;str&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#268bd2&#34;&gt;@app.post&lt;/span&gt;(&lt;span style=&#34;color:#2aa198&#34;&gt;&amp;#34;/chat&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#719e07&#34;&gt;async&lt;/span&gt; &lt;span style=&#34;color:#719e07&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#268bd2&#34;&gt;chat&lt;/span&gt;(req: ChatRequest):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    result &lt;span style=&#34;color:#719e07&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#719e07&#34;&gt;await&lt;/span&gt; rag_chain&lt;span style=&#34;color:#719e07&#34;&gt;.&lt;/span&gt;ainvoke({&lt;span style=&#34;color:#2aa198&#34;&gt;&amp;#34;input&amp;#34;&lt;/span&gt;: req&lt;span style=&#34;color:#719e07&#34;&gt;.&lt;/span&gt;message})&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#719e07&#34;&gt;return&lt;/span&gt; {&lt;span style=&#34;color:#2aa198&#34;&gt;&amp;#34;answer&amp;#34;&lt;/span&gt;: result[&lt;span style=&#34;color:#2aa198&#34;&gt;&amp;#34;answer&amp;#34;&lt;/span&gt;]}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;production-checklist&#34;&gt;Production Checklist&lt;/h2&gt;&#xA;&lt;p&gt;Rate limiting, API keys, structured logging, health checks, timeout on LLM calls, background tasks for long ingest jobs.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Claude API vs OpenAI API: Choosing the Right LLM</title>
      <link>https://www.davidlang.tech/posts/claude-api-vs-openai-api-choosing-the-right-llm/</link>
      <pubDate>Wed, 14 Aug 2024 00:00:00 +0000</pubDate>
      <guid>https://www.davidlang.tech/posts/claude-api-vs-openai-api-choosing-the-right-llm/</guid>
      <description>&lt;p&gt;Anthropic&amp;rsquo;s Claude and OpenAI&amp;rsquo;s GPT families both offer strong APIs. Choosing between them depends on task, context length, cost, and compliance-not benchmark hype alone.&lt;/p&gt;&#xA;&lt;h2 id=&#34;strengths-at-a-glance&#34;&gt;Strengths at a Glance&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;Claude&lt;/strong&gt; - Long context windows, careful refusals, strong long-document analysis and coding reviews.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;OpenAI&lt;/strong&gt; - Broad ecosystem, function calling maturity, image and audio modalities, largest third-party integration surface.&lt;/p&gt;&#xA;&lt;h2 id=&#34;integration-pattern&#34;&gt;Integration Pattern&lt;/h2&gt;&#xA;&lt;p&gt;Abstract the provider behind an interface:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-typescript&#34; data-lang=&#34;typescript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#268bd2&#34;&gt;interface&lt;/span&gt; LLMProvider {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  chat(messages: &lt;span style=&#34;color:#dc322f&#34;&gt;Message&lt;/span&gt;[])&lt;span style=&#34;color:#719e07&#34;&gt;:&lt;/span&gt; Promise&amp;lt;&lt;span style=&#34;color:#268bd2&#34;&gt;string&lt;/span&gt;&amp;gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Swap implementations per route (cheap model for classification, premium for generation).&lt;/p&gt;</description>
    </item>
    <item>
      <title>JWT Authentication: Securing Your REST API</title>
      <link>https://www.davidlang.tech/posts/jwt-authentication-securing-your-rest-api/</link>
      <pubDate>Sat, 05 Sep 2020 00:00:00 +0000</pubDate>
      <guid>https://www.davidlang.tech/posts/jwt-authentication-securing-your-rest-api/</guid>
      <description>&lt;p&gt;JSON Web Tokens (JWT) are a compact way to represent claims between parties. For stateless REST APIs and SPAs, JWT-based auth is a standard pattern-when implemented correctly.&lt;/p&gt;&#xA;&lt;h2 id=&#34;token-structure&#34;&gt;Token Structure&lt;/h2&gt;&#xA;&lt;p&gt;A JWT has three Base64-encoded parts: header, payload, and signature. The server signs the token with a secret (HS256) or private key (RS256). Clients send &lt;code&gt;Authorization: Bearer &amp;lt;token&amp;gt;&lt;/code&gt; on each request.&lt;/p&gt;&#xA;&lt;h2 id=&#34;issuing-tokens-in-nodejs&#34;&gt;Issuing Tokens in Node.js&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#268bd2&#34;&gt;const&lt;/span&gt; jwt &lt;span style=&#34;color:#719e07&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#2aa198&#34;&gt;&amp;#39;jsonwebtoken&amp;#39;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#268bd2&#34;&gt;function&lt;/span&gt; login(req, res) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#268bd2&#34;&gt;const&lt;/span&gt; user &lt;span style=&#34;color:#719e07&#34;&gt;=&lt;/span&gt; validateCredentials(req.body);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#719e07&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#719e07&#34;&gt;!&lt;/span&gt;user) &lt;span style=&#34;color:#719e07&#34;&gt;return&lt;/span&gt; res.status(&lt;span style=&#34;color:#2aa198&#34;&gt;401&lt;/span&gt;).json({ error&lt;span style=&#34;color:#719e07&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#2aa198&#34;&gt;&amp;#39;Invalid credentials&amp;#39;&lt;/span&gt; });&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#268bd2&#34;&gt;const&lt;/span&gt; token &lt;span style=&#34;color:#719e07&#34;&gt;=&lt;/span&gt; jwt.sign(&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    { sub&lt;span style=&#34;color:#719e07&#34;&gt;:&lt;/span&gt; user.id, role&lt;span style=&#34;color:#719e07&#34;&gt;:&lt;/span&gt; user.role },&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    process.env.JWT_SECRET,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    { expiresIn&lt;span style=&#34;color:#719e07&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#2aa198&#34;&gt;&amp;#39;1h&amp;#39;&lt;/span&gt; }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  );&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  res.json({ token });&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;middleware-verification&#34;&gt;Middleware Verification&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#268bd2&#34;&gt;function&lt;/span&gt; authMiddleware(req, res, next) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#268bd2&#34;&gt;const&lt;/span&gt; header &lt;span style=&#34;color:#719e07&#34;&gt;=&lt;/span&gt; req.headers.authorization;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#719e07&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#719e07&#34;&gt;!&lt;/span&gt;header&lt;span style=&#34;color:#719e07&#34;&gt;?&lt;/span&gt;.startsWith(&lt;span style=&#34;color:#2aa198&#34;&gt;&amp;#39;Bearer &amp;#39;&lt;/span&gt;)) &lt;span style=&#34;color:#719e07&#34;&gt;return&lt;/span&gt; res.sendStatus(&lt;span style=&#34;color:#2aa198&#34;&gt;401&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#719e07&#34;&gt;try&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    req.user &lt;span style=&#34;color:#719e07&#34;&gt;=&lt;/span&gt; jwt.verify(header.slice(&lt;span style=&#34;color:#2aa198&#34;&gt;7&lt;/span&gt;), process.env.JWT_SECRET);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    next();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  } &lt;span style=&#34;color:#719e07&#34;&gt;catch&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    res.sendStatus(&lt;span style=&#34;color:#2aa198&#34;&gt;401&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;security-checklist&#34;&gt;Security Checklist&lt;/h2&gt;&#xA;&lt;p&gt;Keep secrets out of source control. Use short expiration and refresh tokens for long sessions. Never store sensitive data in the payload-it is readable. Prefer HTTPS everywhere.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Introduction to GraphQL: Why It Matters</title>
      <link>https://www.davidlang.tech/posts/introduction-to-graphql-why-it-matters/</link>
      <pubDate>Sat, 25 Jul 2020 00:00:00 +0000</pubDate>
      <guid>https://www.davidlang.tech/posts/introduction-to-graphql-why-it-matters/</guid>
      <description>&lt;p&gt;GraphQL is a query language for APIs that lets clients request exactly the fields they need. Unlike REST, you avoid over-fetching and under-fetching by design.&lt;/p&gt;&#xA;&lt;h2 id=&#34;schema-first-design&#34;&gt;Schema-First Design&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-graphql&#34; data-lang=&#34;graphql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#268bd2&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#268bd2&#34;&gt;Query&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  user(id: &lt;span style=&#34;color:#268bd2&#34;&gt;ID&lt;/span&gt;!): &lt;span style=&#34;color:#268bd2&#34;&gt;User&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  posts(limit: &lt;span style=&#34;color:#268bd2&#34;&gt;Int&lt;/span&gt; = 10): [&lt;span style=&#34;color:#268bd2&#34;&gt;Post&lt;/span&gt;!]!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#268bd2&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#268bd2&#34;&gt;User&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  id: &lt;span style=&#34;color:#268bd2&#34;&gt;ID&lt;/span&gt;!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  name: &lt;span style=&#34;color:#268bd2&#34;&gt;String&lt;/span&gt;!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  posts: [&lt;span style=&#34;color:#268bd2&#34;&gt;Post&lt;/span&gt;!]!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Clients send queries that mirror the shape of the response:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-graphql&#34; data-lang=&#34;graphql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#268bd2&#34;&gt;query&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#268bd2&#34;&gt;user&lt;/span&gt;(id: &lt;span style=&#34;color:#2aa198&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#268bd2&#34;&gt;name&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    posts(limit: &lt;span style=&#34;color:#268bd2&#34;&gt;5&lt;/span&gt;) { title createdAt }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;server-implementation&#34;&gt;Server Implementation&lt;/h2&gt;&#xA;&lt;p&gt;Apollo Server and GraphQL Yoga are popular in Node.js. Resolvers map fields to databases or microservices. Use DataLoader to batch N+1 queries.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
