<?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: Cristian Rubio</title>
    <description>The latest articles on DEV Community by Cristian Rubio (@crubio).</description>
    <link>https://dev.to/crubio</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%2F3731633%2F135d6eae-091a-44bc-9c7c-fea3b8579374.jpg</url>
      <title>DEV Community: Cristian Rubio</title>
      <link>https://dev.to/crubio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/crubio"/>
    <language>en</language>
    <item>
      <title>FakeAPI — A Mutable, Isolated REST Sandbox for Testing and Prototyping</title>
      <dc:creator>Cristian Rubio</dc:creator>
      <pubDate>Fri, 29 May 2026 15:21:18 +0000</pubDate>
      <link>https://dev.to/crubio/fakeapi-a-mutable-isolated-rest-sandbox-for-testing-and-prototyping-36i</link>
      <guid>https://dev.to/crubio/fakeapi-a-mutable-isolated-rest-sandbox-for-testing-and-prototyping-36i</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-05-21"&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;FakeAPI&lt;/strong&gt; is a hosted REST API for testing and prototyping — real in-memory CRUD, no database, no auth. You create a workspace and get your own isolated copy of seed data with full CRUD, filtering, sorting, and pagination across Tasks, Users, and Projects.&lt;/p&gt;

&lt;p&gt;There are other tools in this space, but none hit the exact combination I needed:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;JSONPlaceholder&lt;/th&gt;
&lt;th&gt;ReqRes&lt;/th&gt;
&lt;th&gt;MockAPI&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;FakeAPI&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;No signup&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Real CRUD (data actually changes)&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Session isolation (your data is yours)&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pre-loaded seed data&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reset to seed state on demand&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multiple resource types&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;JSONPlaceholder acknowledges your writes but doesn't store them. ReqRes returns hardcoded responses. MockAPI requires an account and you define the schema from scratch. FakeAPI is the only one that gives you real, mutable, isolated data without any setup.&lt;/p&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Live: &lt;a href="https://fakeapi-kynw.onrender.com" rel="noopener noreferrer"&gt;https://fakeapi-kynw.onrender.com&lt;/a&gt;&lt;/strong&gt; &lt;em&gt;(free tier — first request may take ~1 min to wake the server)&lt;/em&gt;&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="c"&gt;# Create your isolated workspace&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://fakeapi-kynw.onrender.com/api/workspaces/

&lt;span class="c"&gt;# Browse pre-loaded tasks, users, projects&lt;/span&gt;
curl &lt;span class="s2"&gt;"https://fakeapi-kynw.onrender.com/api/workspaces/{id}/tasks/?status=pending&amp;amp;sort_by=-created_at"&lt;/span&gt;

&lt;span class="c"&gt;# Reset to seed state any time&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://fakeapi-kynw.onrender.com/api/workspaces/&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;/reset
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interactive docs: &lt;a href="https://fakeapi-kynw.onrender.com/docs" rel="noopener noreferrer"&gt;https://fakeapi-kynw.onrender.com/docs&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Comeback Story
&lt;/h2&gt;

&lt;p&gt;I built a rough first version in February 2025, deployed it to Render, and forgot about it for 15 months.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt; — a single &lt;code&gt;/tasks&lt;/code&gt; endpoint backed by statically generated fake data using &lt;code&gt;faker&lt;/code&gt;. No real storage, no isolation, no CRUD. Every caller saw the same global state and couldn't change anything that persisted. The README was one line. There were no tests, no deployment worth sharing beyond a proof of concept.&lt;/p&gt;

&lt;p&gt;The core problem was that I'd solved the wrong thing: I had endpoints that returned data, but not an API you could actually use to build or test something. If you created a task, it was gone on the next request. If two people hit it at the same time, they'd interfere with each other. It was a demo, not a tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt; — the architecture changed completely. Workspaces became the central concept: each caller gets their own in-memory copy of all seed data, isolated from everyone else. You can create, update, delete — and none of it bleeds into another session. A background loop cleans up expired workspaces hourly, each one lives 24 hours and can be extended up to three times.&lt;/p&gt;

&lt;p&gt;On top of that: three full resources (Tasks, Users, Projects) with filtering, sorting, and pagination; nested routes like &lt;code&gt;GET /users/{id}/tasks&lt;/code&gt;; rate limiting; a full test suite with a coverage gate enforced in CI; a GitHub Actions pipeline; and a landing page.&lt;/p&gt;




&lt;h2&gt;
  
  
  My Experience with GitHub Copilot
&lt;/h2&gt;

&lt;p&gt;My background is backend. I'm comfortable with Python, APIs, and data modeling — but when it came to building the landing page, I was starting from scratch.&lt;/p&gt;

&lt;p&gt;The design I had in mind was a terminal-style interface: monospaced font, a fake browser bar with colored dots, dark mode toggle that persists across sessions. I knew what I wanted visually, but I didn't know CSS well enough to build it confidently. Copilot bridged that gap. I'd describe what I wanted — "a sticky header with a theme toggle that switches between light and dark using CSS variables and saves the preference to localStorage" — and it would give me something that worked. I'd tweak, ask again, and iterate.&lt;/p&gt;

&lt;p&gt;What surprised me was how much I actually learned in the process. Because Copilot explained the patterns it used — CSS custom properties, the &lt;code&gt;data-theme&lt;/code&gt; attribute approach, the FOUC prevention trick with an inline script before the CSS loads — I came out understanding the code, not just having it. That felt like the right way to use the tool.&lt;/p&gt;




&lt;p&gt;If you're building a frontend, testing an HTTP client, or just need a realistic API without the setup overhead, give it a try.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/cristianrubioa/fakeapi" rel="noopener noreferrer"&gt;github.com/cristianrubioa/fakeapi&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
    </item>
    <item>
      <title>MeshChat — A Zero-Install Terminal Chat Room Built with GitHub Copilot CLI</title>
      <dc:creator>Cristian Rubio</dc:creator>
      <pubDate>Sat, 14 Feb 2026 03:58:33 +0000</pubDate>
      <link>https://dev.to/crubio/meshchat-a-zero-install-terminal-chat-room-built-with-github-copilot-cli-3072</link>
      <guid>https://dev.to/crubio/meshchat-a-zero-install-terminal-chat-room-built-with-github-copilot-cli-3072</guid>
      <description>&lt;h2&gt;
  
  
  🚀 What I built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;MeshChat&lt;/strong&gt; is a terminal-based chat server written in &lt;strong&gt;Python (asyncio)&lt;/strong&gt; that lets anyone join a shared chat room using nothing more than:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nc &amp;lt;host&amp;gt; &amp;lt;port&amp;gt;
&lt;span class="c"&gt;# or&lt;/span&gt;
telnet &amp;lt;host&amp;gt; &amp;lt;port&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No client binaries.&lt;br&gt;&lt;br&gt;
No accounts.&lt;br&gt;&lt;br&gt;
No setup on the user side.&lt;/p&gt;

&lt;p&gt;If you can open a terminal, you can chat.&lt;/p&gt;

&lt;p&gt;Repository: &lt;a href="https://github.com/cristianrubioa/meshchat" rel="noopener noreferrer"&gt;https://github.com/cristianrubioa/meshchat&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  💡 Why I built it
&lt;/h2&gt;

&lt;p&gt;Sometimes you just need a &lt;strong&gt;quick local chat room&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A small team on the same network
&lt;/li&gt;
&lt;li&gt;A classroom or lab
&lt;/li&gt;
&lt;li&gt;A hackathon
&lt;/li&gt;
&lt;li&gt;A home LAN
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted something that felt like an old-school LAN chat, but with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;modern async Python
&lt;/li&gt;
&lt;li&gt;a clean CLI
&lt;/li&gt;
&lt;li&gt;colorful output
&lt;/li&gt;
&lt;li&gt;basic safety (rate limits, message caps)
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MeshChat turns a TCP port into a friendly shared room.&lt;/p&gt;


&lt;h2&gt;
  
  
  ✨ Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Zero client setup — connect via &lt;code&gt;nc&lt;/code&gt; or &lt;code&gt;telnet&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Colorful UI — each user gets a unique ANSI color&lt;/li&gt;
&lt;li&gt;Chat commands:

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/who&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/me&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/help&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/quit&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Optional message history&lt;/li&gt;
&lt;li&gt;Rate limiting (anti-spam)&lt;/li&gt;
&lt;li&gt;Async I/O with &lt;code&gt;asyncio&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Typer-based CLI&lt;/li&gt;
&lt;li&gt;Rich terminal formatting&lt;/li&gt;
&lt;li&gt;Environment + CLI configuration&lt;/li&gt;
&lt;li&gt;Tested with &lt;code&gt;pytest&lt;/code&gt; and &lt;code&gt;pytest-asyncio&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🧠 How GitHub Copilot CLI helped
&lt;/h2&gt;

&lt;p&gt;I used GitHub Copilot CLI as my “terminal pair programmer” during the entire build.&lt;/p&gt;

&lt;p&gt;Biggest productivity wins:&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Architecture scaffolding
&lt;/h3&gt;

&lt;p&gt;Copilot CLI helped propose a clean modular layout:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;network server
&lt;/li&gt;
&lt;li&gt;room state
&lt;/li&gt;
&lt;li&gt;client lifecycle
&lt;/li&gt;
&lt;li&gt;UI formatting
&lt;/li&gt;
&lt;li&gt;command handling
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This let me move fast from a prototype to a maintainable package.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Async networking flows
&lt;/h3&gt;

&lt;p&gt;Copilot CLI assisted with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;asyncio.start_server&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;client connect / disconnect handling&lt;/li&gt;
&lt;li&gt;broadcast fan-out&lt;/li&gt;
&lt;li&gt;graceful cleanup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These parts are easy to get wrong — Copilot accelerated iteration a lot.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. UX polish
&lt;/h3&gt;

&lt;p&gt;Instead of manually researching Rich + ANSI patterns, I prompted Copilot CLI for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;per-user colors
&lt;/li&gt;
&lt;li&gt;action messages (&lt;code&gt;/me&lt;/code&gt;)
&lt;/li&gt;
&lt;li&gt;formatted system events
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Result: better terminal UX with less friction.&lt;/p&gt;
&lt;h3&gt;
  
  
  4. Guardrails
&lt;/h3&gt;

&lt;p&gt;Copilot CLI helped implement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;nickname limits
&lt;/li&gt;
&lt;li&gt;max message length
&lt;/li&gt;
&lt;li&gt;rate limiting windows
&lt;/li&gt;
&lt;li&gt;max users
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This made MeshChat safer by default.&lt;/p&gt;
&lt;h3&gt;
  
  
  5. Tests
&lt;/h3&gt;

&lt;p&gt;I used Copilot CLI to generate pytest-asyncio skeletons and refine edge cases like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;multiple clients&lt;/li&gt;
&lt;li&gt;broadcast correctness&lt;/li&gt;
&lt;li&gt;command parsing&lt;/li&gt;
&lt;li&gt;reconnect behavior&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Example prompts (high level)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;“Generate an asyncio TCP chat server with shared rooms.”&lt;/li&gt;
&lt;li&gt;“Add a Typer CLI with port, room name, history options.”&lt;/li&gt;
&lt;li&gt;“Suggest a clean Python package structure for this project.”&lt;/li&gt;
&lt;li&gt;“Write pytest-asyncio tests for multi-client broadcast.”&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  ⚡ Quick start
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Install
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;poetry &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Run server
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;poetry run meshchat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;poetry run meshchat &lt;span class="nt"&gt;--port&lt;/span&gt; 2323 &lt;span class="nt"&gt;--room-name&lt;/span&gt; &lt;span class="s2"&gt;"My Room"&lt;/span&gt; &lt;span class="nt"&gt;--history&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Join
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nc localhost 2323
&lt;span class="c"&gt;# or&lt;/span&gt;
telnet localhost 2323
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  💬 Chat commands
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/who&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List connected users&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/me &amp;lt;action&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Action message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/help&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show help&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/quit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Disconnect&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🧱 Architecture (high level)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;meshchat/
├── chatserver/
│   ├── core/        # room, client, message logic
│   ├── network/     # asyncio TCP server
│   ├── ui/          # ANSI/Rich formatting
│   └── main.py      # CLI entry point
└── test/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Flow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TCP server accepts connections&lt;/li&gt;
&lt;li&gt;Each socket becomes a Client&lt;/li&gt;
&lt;li&gt;All clients join a shared Room&lt;/li&gt;
&lt;li&gt;Messages broadcast to everyone&lt;/li&gt;
&lt;li&gt;Formatter styles output&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🙏 Inspiration
&lt;/h2&gt;

&lt;p&gt;Inspired by the Go project &lt;code&gt;chat-tails&lt;/code&gt;. &lt;a href="https://github.com/bscott/chat-tails" rel="noopener noreferrer"&gt;repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MeshChat is a Python-first reimplementation with its own:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;async architecture
&lt;/li&gt;
&lt;li&gt;CLI UX
&lt;/li&gt;
&lt;li&gt;rate limiting
&lt;/li&gt;
&lt;li&gt;configuration system
&lt;/li&gt;
&lt;li&gt;development guide
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔮 What’s next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Optional room passwords&lt;/li&gt;
&lt;li&gt;Multiple rooms (channels)&lt;/li&gt;
&lt;li&gt;Docker image&lt;/li&gt;
&lt;li&gt;Presence events (join/leave notifications)&lt;/li&gt;
&lt;li&gt;Server-side logging&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🏁 Final thoughts
&lt;/h2&gt;

&lt;p&gt;This project was a great way to explore what’s possible when AI meets the terminal.&lt;/p&gt;

&lt;p&gt;Using GitHub Copilot CLI directly from my shell made experimentation fast, fun, and surprisingly productive — especially for async networking and CLI tooling.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;p&gt;Happy hacking 👋&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
      <category>cli</category>
      <category>githubcopilot</category>
    </item>
  </channel>
</rss>
