<?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: Alexander Komyagin</title>
    <description>The latest articles on DEV Community by Alexander Komyagin (@adkomyagin).</description>
    <link>https://dev.to/adkomyagin</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%2F2213258%2Fcfe56b25-a169-4764-8127-f156c5fc7f04.jpg</url>
      <title>DEV Community: Alexander Komyagin</title>
      <link>https://dev.to/adkomyagin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/adkomyagin"/>
    <language>en</language>
    <item>
      <title>Vibe Code Like a Pro: Build an MVP Web App with MongoDB Atlas in &lt;1 Hour Using Cursor</title>
      <dc:creator>Alexander Komyagin</dc:creator>
      <pubDate>Wed, 14 May 2025 17:30:00 +0000</pubDate>
      <link>https://dev.to/adkomyagin/vibe-code-like-a-pro-build-an-mvp-web-app-with-mongodb-atlas-in-1-hour-using-cursor-4i2k</link>
      <guid>https://dev.to/adkomyagin/vibe-code-like-a-pro-build-an-mvp-web-app-with-mongodb-atlas-in-1-hour-using-cursor-4i2k</guid>
      <description>&lt;p&gt;&lt;em&gt;How to harness AI vibecoding without creating a backend mess&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fud49nwaej175clqae6l0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fud49nwaej175clqae6l0.png" alt="Vibecoded movie catalog app" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Tutorial?
&lt;/h2&gt;

&lt;p&gt;Vibecoding is trending right now, and I've seen firsthand how AI can dramatically accelerate development. But there's a catch — AI-generated “quick prototypes” morph into weeks of debugging auth issues, inconsistent data models, and leaky abstractions. In this tutorial, I'll show you how I built a secure, scalable movie catalog MVP in under an hour using &lt;a href="https://cursor.com/" rel="noopener noreferrer"&gt;Cursor&lt;/a&gt; (AI-powered code editor) and &lt;a href="https://adiom.io/" rel="noopener noreferrer"&gt;Adiom’s&lt;/a&gt; Data API (a declarative backend service).&lt;/p&gt;

&lt;h2&gt;
  
  
  Who Am I?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;I have worked with MongoDB and other databases for a long time&lt;/li&gt;
&lt;li&gt;I have very strong backend experience (mainly Go and Java)&lt;/li&gt;
&lt;li&gt;I'm able to read and understand Typescript and JS, and have modest familiarity with modern frameworks like NextJS, but I'm far from being a frontend expert&lt;/li&gt;
&lt;li&gt;Vibecoding skeptic turning advocate: I tested 8+ AI tools (Replit, v0, Claude, Cursor, others) – most create “throwaway” code. Here’s how to avoid that.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The MVP Requirements
&lt;/h2&gt;

&lt;p&gt;Rather than creating a yet another throwaway demo, I wanted to see if I could leverage AI to build something &lt;strong&gt;MVP-grade&lt;/strong&gt; using existing sample data in MongoDB Atlas from the &lt;code&gt;sample_mflix&lt;/code&gt; &lt;a href="https://www.mongodb.com/docs/atlas/sample-data/sample-mflix/" rel="noopener noreferrer"&gt;dataset&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Google OAuth sign-in&lt;/li&gt;
&lt;li&gt;Paginated movie browsing&lt;/li&gt;
&lt;li&gt;User-specific favorite movies&lt;/li&gt;
&lt;li&gt;Secure backend (auth/authz)&lt;/li&gt;
&lt;li&gt;No tightly coupled DB logic in frontend&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Problem With Pure Vibecoding
&lt;/h2&gt;

&lt;p&gt;I was really impressed with agentic workflows in Replit and Cursor. But when I tried to generate the whole application with AI tools alone:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;20 min: First “working” prototype&lt;/li&gt;
&lt;li&gt;2 days later: Discovered 3 different data models (one of them was for PostgreSQL somehow?), zero authz, a bunch of dead code, and API endpoints that do inexplicable things 😱&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Key lesson: AI excels at code generation, not architectural decisions.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Like one of my friends said, who's a CTO of this cool firm Caylent that specializes in app dev: "as consultants we get brought into vibe coded messes that have repeated data models everywhere and no coherence."&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Secret Sauce: Decoupling Data Access
&lt;/h2&gt;

&lt;p&gt;The key to accelerating development without sacrificing quality lies in properly abstracting the data layer. This is where &lt;a href="https://adiom.gitbook.io/data-api" rel="noopener noreferrer"&gt;Adiom's Data API&lt;/a&gt; comes in — a declarative backend service that creates a well-defined, secure data access layer almost instantly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl2l1blgh5mjbvjltgasw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl2l1blgh5mjbvjltgasw.png" alt="Adiom's Data API" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instead of letting AI directly touch the database, by using this approach, we can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ground the AI code generation with a robust semantic data layer&lt;/li&gt;
&lt;li&gt;Enforce well-structured data access patterns&lt;/li&gt;
&lt;li&gt;Provide type-safe, versioned endpoints&lt;/li&gt;
&lt;li&gt;Implement proper authorization rules&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Result: Vibecoding stays within guardrails, avoiding backend chaos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparation: Set up Atlas Cluster
&lt;/h2&gt;

&lt;p&gt;Set up an Atlas Cluster at &lt;a href="//cloud.mongodb.com"&gt;cloud.mongodb.com&lt;/a&gt; and load the &lt;code&gt;sample_mflix&lt;/code&gt; &lt;a href="https://www.mongodb.com/docs/atlas/sample-data/sample-mflix/" rel="noopener noreferrer"&gt;dataset&lt;/a&gt;. A free tier cluster will work fine for this.&lt;/p&gt;

&lt;p&gt;Add &lt;strong&gt;35.247.121.225&lt;/strong&gt; (hosted Data API service IP) to &lt;a href="https://www.mongodb.com/docs/atlas/security/ip-access-list/" rel="noopener noreferrer"&gt;Atlas Cluster IP whitelist&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Define The Data Model with Protocol Buffers
&lt;/h2&gt;

&lt;p&gt;First, we need to define our data model and API endpoints using &lt;a href="https://protobuf.dev/" rel="noopener noreferrer"&gt;Protocol Buffers&lt;/a&gt;. They are an industry standard when it comes to low-latency, high-performance data serialization.&lt;/p&gt;

&lt;p&gt;Since we're using an existing MongoDB instance, I used Claude with &lt;a href="https://github.com/mongodb-js/mongodb-mcp-server" rel="noopener noreferrer"&gt;MongoDB's MCP server&lt;/a&gt; to help generate the proto file based on schema analysis.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F691veec70kr3yfvjaj1j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F691veec70kr3yfvjaj1j.png" alt="Generating proto with Claude" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Output: Clean, versioned schema that required some tweaking (&lt;a href="https://github.com/alex-thc/vibecode-movie-catalog/blob/master/dapi_files/movie.proto" rel="noopener noreferrer"&gt;final version&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The proto file needs to be compiled with the &lt;code&gt;buf&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;buf build -o protos.pb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Create a Config File for Data API
&lt;/h2&gt;

&lt;p&gt;Next, create a YAML configuration file that tells the Data API how to implement these endpoints and what authorization rules to apply (&lt;a href="https://github.com/alex-thc/vibecode-movie-catalog/blob/master/dapi_files/config.yml" rel="noopener noreferrer"&gt;full config file&lt;/a&gt;):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffnxinxmnm5uox52q2g3r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffnxinxmnm5uox52q2g3r.png" alt="Data API config file" width="778" height="558"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Key points in the configuration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Single connection to MongoDB Atlas&lt;/li&gt;
&lt;li&gt;Per-endpoint authorization rules&lt;/li&gt;
&lt;li&gt;JWK token validation for security&lt;/li&gt;
&lt;li&gt;Custom queries for accessing and modifying data&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 3: Deploy the Backend in 3 Clicks
&lt;/h2&gt;

&lt;p&gt;With the proto and configuration files ready, deploy the backend service in the &lt;a href="https://dapi-sandbox.adiom.io/" rel="noopener noreferrer"&gt;Data API sandbox for MongoDB Atlas&lt;/a&gt;. This step requires just a few clicks and no additional coding.&lt;/p&gt;

&lt;p&gt;The Data API automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates all the necessary endpoints based on our proto definitions&lt;/li&gt;
&lt;li&gt;Implements the authorization rules&lt;/li&gt;
&lt;li&gt;Connects securely to MongoDB Atlas&lt;/li&gt;
&lt;li&gt;Provides monitoring and observability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ik9k5esppdnkaumx0kr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ik9k5esppdnkaumx0kr.png" alt="Adiom's Data API metrics" width="800" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Vibe-Code the Frontend (Cursor Time!)
&lt;/h2&gt;

&lt;p&gt;I used Cursor with a Magic prompt to generate the frontend. The prompt included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Application requirements&lt;/li&gt;
&lt;li&gt;The proto file we created&lt;/li&gt;
&lt;li&gt;Instructions for establishing RPC connections and code generation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6cx8nckmjee6sntl3cvq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6cx8nckmjee6sntl3cvq.png" alt="Cursor is generating the app based on our prompt" width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The full prompt that I used can be found &lt;a href="https://github.com/alex-thc/vibecode-movie-catalog/blob/master/dapi_files/prompt.txt" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Cursor generated a working React application that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implements Google Sign-In&lt;/li&gt;
&lt;li&gt;Shows paginated movie listings&lt;/li&gt;
&lt;li&gt;Allows users to mark favorites&lt;/li&gt;
&lt;li&gt;Connects to our Data API backend&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I only needed minimal "vibe-debugging" to fix a few minor issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results &amp;amp; Takeaways
&lt;/h2&gt;

&lt;p&gt;In under an hour, we built an MVP-grade movie catalog web app with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Proper authentication and authorization&lt;/li&gt;
&lt;li&gt;Clean separation between frontend and backend&lt;/li&gt;
&lt;li&gt;Type-safe API contracts&lt;/li&gt;
&lt;li&gt;Monitoring and observability for backend endpoints&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Vibecoding Wisdoms
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;AI needs &lt;em&gt;constraints&lt;/em&gt; (semantic API specification via protobufs)&lt;/li&gt;
&lt;li&gt;Never let LLMs make authz and data model decisions&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;p&gt;Find the complete code and instructions in &lt;a href="https://github.com/alex-thc/vibecode-movie-catalog" rel="noopener noreferrer"&gt;this GitHub repository&lt;/a&gt;. All you need is a MongoDB Atlas cluster to get started.&lt;/p&gt;

&lt;p&gt;We have plans to release the Data API project under an Open Source license, but in the meantime we are making a free hosted sandbox available for the &lt;strong&gt;first 50 users&lt;/strong&gt; who register at &lt;a href="https://dapi-sandbox.adiom.io/" rel="noopener noreferrer"&gt;dapi-sandbox.adiom.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Questions or want to learn more?&lt;/strong&gt; Add your comments here or join us on &lt;a href="https://discord.gg/r4xzVfMQeU" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; - I'll personally help troubleshoot! &lt;/p&gt;

&lt;p&gt;Happy vibecoding!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>vibecoding</category>
      <category>mongodb</category>
      <category>genai</category>
    </item>
  </channel>
</rss>
