<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>SwiftModelGraph Blog</title>
        <link>https://phonepe.github.io/SwiftModelGraph/blog</link>
        <description>SwiftModelGraph Blog</description>
        <lastBuildDate>Mon, 10 Mar 2025 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Introducing ModelGraphGenerator]]></title>
            <link>https://phonepe.github.io/SwiftModelGraph/blog/welcome</link>
            <guid>https://phonepe.github.io/SwiftModelGraph/blog/welcome</guid>
            <pubDate>Mon, 10 Mar 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[We're excited to announce the open-source release of ModelGraphGenerator — a command-line tool that automatically generates JSON Schema from your annotated Swift models.]]></description>
            <content:encoded><![CDATA[<p>We're excited to announce the open-source release of <strong>ModelGraphGenerator</strong> — a command-line tool that automatically generates JSON Schema from your annotated Swift models.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-problem">The Problem<a href="https://phonepe.github.io/SwiftModelGraph/blog/welcome#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem">​</a></h2>
<p>If you've ever maintained a Swift API or SDK, you know the pain: your Swift models and their JSON Schema representations drift apart over time. Schema changes require manual updates in two separate places. It's easy to miss a field, get a type wrong, or forget to add a constraint to the schema.</p>
<p>We built ModelGraphGenerator internally at PhonePe to solve this. Today, we're sharing it with the community.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="how-it-works">How It Works<a href="https://phonepe.github.io/SwiftModelGraph/blog/welcome#how-it-works" class="hash-link" aria-label="Direct link to How It Works" title="Direct link to How It Works">​</a></h2>
<p>Annotate any Swift <code>struct</code> or <code>class</code> with <code>@ChimeraSchema</code>, add <code>@ChimeraProperty</code> annotations to your properties, and run the CLI:</p>
<div class="language-swift codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-swift codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token attribute atrule" style="color:#00a4db">@ChimeraMetaData</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">description</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:#e3116c">"A payment transaction"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token attribute atrule" style="color:#00a4db">@ChimeraSchema</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">key</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:#e3116c">"payment"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token class-name">Payment</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attribute atrule" style="color:#00a4db">@ChimeraProperty</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">description</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:#e3116c">"Transaction ID"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> transactionId</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attribute atrule" style="color:#00a4db">@ChimeraProperty</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">description</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:#e3116c">"Amount in USD"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> min</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> amount</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Double</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attribute atrule" style="color:#00a4db">@ChimeraProperty</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">description</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string-literal string" style="color:#e3116c">"Payment status"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> status</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">PaymentStatus</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">model-graph-generator --source-path ./Sources </span><span class="token parameter variable" style="color:#36acaa">--output</span><span class="token plain"> schema.json --json-schema</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>That's it. You get a complete JSON Schema Draft 2020-12 document.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="key-features">Key Features<a href="https://phonepe.github.io/SwiftModelGraph/blog/welcome#key-features" class="hash-link" aria-label="Direct link to Key Features" title="Direct link to Key Features">​</a></h2>
<p><strong>Multi-Strategy Discovery</strong><br>
<!-- -->ModelGraphGenerator finds your annotated types using both macro scanning and IndexStoreDB, giving you flexibility in how you structure your project.</p>
<p><strong>Polymorphic Types</strong><br>
<!-- -->Support for <code>oneOf</code> schemas via <code>@PolymorphicMapping</code>, with discriminator fields for code generators and validators.</p>
<p><strong>CodingKeys Support</strong><br>
<!-- -->If you've defined custom <code>CodingKeys</code>, ModelGraphGenerator respects them in the generated schema.</p>
<p><strong>Cycle Detection</strong><br>
<!-- -->Circular model references are detected and handled gracefully — no infinite loops.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="whats-next">What's Next<a href="https://phonepe.github.io/SwiftModelGraph/blog/welcome#whats-next" class="hash-link" aria-label="Direct link to What's Next" title="Direct link to What's Next">​</a></h2>
<p>This is v1.0.0 — the foundation. Here's what we're planning:</p>
<ul>
<li><strong>DocC integration</strong> — Browse the API docs alongside the CLI docs</li>
<li><strong>Interactive schema explorer</strong> — Explore generated schemas directly in the browser</li>
<li><strong>OpenAPI export</strong> — First-class OpenAPI 3.1 components output</li>
<li><strong>Xcode plugin</strong> — Generate schemas directly from Xcode's build phases</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="get-started">Get Started<a href="https://phonepe.github.io/SwiftModelGraph/blog/welcome#get-started" class="hash-link" aria-label="Direct link to Get Started" title="Direct link to Get Started">​</a></h2>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">git</span><span class="token plain"> clone https://github.com/PhonePe/ModelGraphGenerator.git</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin class-name">cd</span><span class="token plain"> ModelGraphGenerator</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">swift build </span><span class="token parameter variable" style="color:#36acaa">-c</span><span class="token plain"> release</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Read the full <a href="https://phonepe.github.io/SwiftModelGraph/docs/quick-start">Getting Started guide</a> or dive into the <a href="https://phonepe.github.io/SwiftModelGraph/docs/guides/annotations">annotation reference</a>.</p>
<p>We'd love your feedback — open an issue, start a discussion, or send a PR. Thank you for checking it out.</p>]]></content:encoded>
            <author>sharang.verma@phonepe.com (Sharang Verma)</author>
            <category>release</category>
            <category>announcement</category>
        </item>
    </channel>
</rss>