<?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: Joshua Pozos</title>
    <description>The latest articles on DEV Community by Joshua Pozos (@joshuapozos).</description>
    <link>https://dev.to/joshuapozos</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%2F459915%2Fe869f24f-a335-49ea-b811-c4392ba120cf.jpeg</url>
      <title>DEV Community: Joshua Pozos</title>
      <link>https://dev.to/joshuapozos</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/joshuapozos"/>
    <language>en</language>
    <item>
      <title>I built a local Contentful model simulator to stop testing content models blindly</title>
      <dc:creator>Joshua Pozos</dc:creator>
      <pubDate>Sat, 18 Apr 2026 21:54:24 +0000</pubDate>
      <link>https://dev.to/joshuapozos/i-built-a-local-contentful-model-simulator-to-stop-testing-content-models-blindly-n4k</link>
      <guid>https://dev.to/joshuapozos/i-built-a-local-contentful-model-simulator-to-stop-testing-content-models-blindly-n4k</guid>
      <description>&lt;p&gt;When you work with Contentful long enough, you start noticing how much model work is still too easy to do blindly.&lt;/p&gt;

&lt;p&gt;You change a field, push it, inspect it in a real space, realize something is off, undo it, tweak it again, and repeat. It gets worse when you are planning a migration and you cannot really see how the content will look until you import it into Contentful and deal with the fallout there. That loop is slow, clumsy, and riskier than it should be.&lt;/p&gt;

&lt;p&gt;That is why I started building &lt;strong&gt;content-model-simulator&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is not finished yet. This is still a work in progress. But &lt;strong&gt;v0.3.0 is already out&lt;/strong&gt;, and my target is to reach &lt;strong&gt;v1.0.0 by the end of May&lt;/strong&gt;. The point of this post is not to pretend the tool is done. The point is to show the problem I am trying to solve, what already works, and what I have learned while building it.&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%2F3m89c70vy226zta73j5o.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%2F3m89c70vy226zta73j5o.png" alt="Content browser showing entries list, field panel, and a linked reference" width="800" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;I do not like testing content models directly in a real Contentful space unless I absolutely have to.&lt;/p&gt;

&lt;p&gt;For simple changes, maybe that is fine. But once the model starts getting more connected, localized, or migration-heavy, working directly against a live space becomes awkward. You are not really designing anymore. You are poking the system and hoping the shape in your head matches the shape in the CMS.&lt;/p&gt;

&lt;p&gt;And the pain is not only about content types.&lt;/p&gt;

&lt;p&gt;It is also about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;seeing how entries will actually look&lt;/li&gt;
&lt;li&gt;spotting broken assumptions before import&lt;/li&gt;
&lt;li&gt;validating references&lt;/li&gt;
&lt;li&gt;checking how localized content behaves&lt;/li&gt;
&lt;li&gt;understanding whether an existing migration script really produces the model you think it does&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the gap I wanted to attack.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I am building
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;content-model-simulator&lt;/code&gt; is a local-first simulator for Contentful content models.&lt;/p&gt;

&lt;p&gt;The core idea is simple: define schemas locally, point the tool at real data or mock data, and inspect the result in a browser before touching your real Contentful space. The project is explicitly positioned as a &lt;strong&gt;simulation tool&lt;/strong&gt;, not a migration runner, and its README is pretty clear about that boundary.&lt;/p&gt;

&lt;p&gt;Today, it already supports things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;offline simulation of content types, entries, references, and validation errors&lt;/li&gt;
&lt;li&gt;a Content Browser UI to inspect entries and follow references&lt;/li&gt;
&lt;li&gt;a Content Model Graph to visualize relationships&lt;/li&gt;
&lt;li&gt;mock data generation for designing from scratch&lt;/li&gt;
&lt;li&gt;pulling a content model from Contentful for local preview&lt;/li&gt;
&lt;li&gt;migration preview from external sources like WordPress XML or Sanity NDJSON&lt;/li&gt;
&lt;li&gt;CI-friendly validation&lt;/li&gt;
&lt;li&gt;converting existing &lt;code&gt;contentful-migration&lt;/code&gt; scripts into local schemas with &lt;code&gt;from-migrations&lt;/code&gt;, which landed in &lt;strong&gt;v0.3.0&lt;/strong&gt;
&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%2Fmsppabk2siycqfol2xvi.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%2Fmsppabk2siycqfol2xvi.png" alt="Content model graph with multiple content types and relationships" width="800" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I built it this way
&lt;/h2&gt;

&lt;p&gt;I did not want another tool that only sounded useful in theory.&lt;/p&gt;

&lt;p&gt;I wanted something that matched a real workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;define or pull a model&lt;/li&gt;
&lt;li&gt;inspect it locally&lt;/li&gt;
&lt;li&gt;preview entries&lt;/li&gt;
&lt;li&gt;validate the structure&lt;/li&gt;
&lt;li&gt;reduce the chance of breaking something once the real migration or implementation starts&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is the part I care about most: &lt;strong&gt;reducing stupid risk before it reaches a real space&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In other words, this is less about “look, I built a package” and more about “I am trying to make Contentful model work less fragile.”&lt;/p&gt;

&lt;h2&gt;
  
  
  What v0.3.0 already gave me
&lt;/h2&gt;

&lt;p&gt;The new piece in &lt;strong&gt;v0.3.0&lt;/strong&gt; that I am especially happy about is &lt;code&gt;from-migrations&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A lot of teams already use &lt;code&gt;contentful-migration&lt;/code&gt; files as the source of truth for their models. So instead of forcing people to manually rewrite that thinking into another format, I wanted a way to convert migration scripts into simulator schemas and preview them locally. The current changelog describes &lt;code&gt;from-migrations&lt;/code&gt; as a subcommand that converts &lt;code&gt;contentful-migration&lt;/code&gt; scripts into &lt;code&gt;cms-sim&lt;/code&gt; schema files without needing a Contentful connection.&lt;/p&gt;

&lt;p&gt;That matters because it moves the tool closer to a real engineering workflow, not just a demo workflow.&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;# Convert your existing contentful-migration files to cms-sim schemas&lt;/span&gt;
npx cms-sim from-migrations &lt;span class="nt"&gt;--migrations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./migrations/ &lt;span class="nt"&gt;--output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./schemas/

&lt;span class="c"&gt;# Preview the resulting content model locally&lt;/span&gt;
npx cms-sim &lt;span class="nt"&gt;--schemas&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./schemas/ &lt;span class="nt"&gt;--open&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your migration files are TypeScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx tsx &lt;span class="si"&gt;$(&lt;/span&gt;which cms-sim&lt;span class="si"&gt;)&lt;/span&gt; from-migrations &lt;span class="nt"&gt;--migrations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./migrations/ &lt;span class="nt"&gt;--output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./schemas/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What it is not
&lt;/h2&gt;

&lt;p&gt;This tool does &lt;strong&gt;not&lt;/strong&gt; replace Contentful.&lt;/p&gt;

&lt;p&gt;It does &lt;strong&gt;not&lt;/strong&gt; upload, create, or modify anything in your space during simulation. It does &lt;strong&gt;not&lt;/strong&gt; run the actual migration for you either. The package README is explicit: this is a simulator, not a migration tool. The goal is to help you inspect, validate, and think more clearly before you use Contentful’s own tooling for the real operation.&lt;/p&gt;

&lt;p&gt;That distinction matters. I would rather be precise than oversell it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned while building it
&lt;/h2&gt;

&lt;p&gt;A few things became obvious once I started building this.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Content modeling is not only structure, it is behavior
&lt;/h3&gt;

&lt;p&gt;It is easy to think a content model is just fields and types. It is not.&lt;/p&gt;

&lt;p&gt;The real pain appears when you factor in references, locales, validation rules, migration paths, editor expectations, and how actual content will sit inside the model. A model can look fine on paper and still be terrible in practice.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Preview changes how you think
&lt;/h3&gt;

&lt;p&gt;The moment you can inspect entries and relationships locally, the conversation changes.&lt;/p&gt;

&lt;p&gt;You stop arguing only at the schema level. You start noticing editorial friction, broken assumptions, weird relationships, and validation gaps earlier. That is where the value is.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Existing migration scripts are too valuable to ignore
&lt;/h3&gt;

&lt;p&gt;If a team already invested in &lt;code&gt;contentful-migration&lt;/code&gt;, that work should not be trapped in a one-way execution path. Being able to extract value from those scripts for local preview feels like the right direction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick example of the intended workflow
&lt;/h2&gt;

&lt;p&gt;This is the kind of loop I want the tool to support:&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;# Install&lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;content-model-simulator

&lt;span class="c"&gt;# Scaffold a new project with example schemas&lt;/span&gt;
npx cms-sim init

&lt;span class="c"&gt;# Simulate and open the Content Browser&lt;/span&gt;
npx cms-sim &lt;span class="nt"&gt;--schemas&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;schemas/ &lt;span class="nt"&gt;--open&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, once you already have migration scripts:&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;# Convert contentful-migration files → local schemas&lt;/span&gt;
npx cms-sim from-migrations &lt;span class="nt"&gt;--migrations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./migrations/ &lt;span class="nt"&gt;--output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./schemas/

&lt;span class="c"&gt;# Preview without touching Contentful&lt;/span&gt;
npx cms-sim &lt;span class="nt"&gt;--schemas&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./schemas/ &lt;span class="nt"&gt;--open&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if you are working with an existing Contentful space:&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;# Pull the content model from your space (read-only, CDA token)&lt;/span&gt;
npx cms-sim pull &lt;span class="nt"&gt;--space-id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;YOUR_SPACE_ID &lt;span class="nt"&gt;--access-token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;YOUR_CDA_TOKEN

&lt;span class="c"&gt;# Simulate locally against the pulled schemas&lt;/span&gt;
npx cms-sim &lt;span class="nt"&gt;--schemas&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./pulled/schemas/ &lt;span class="nt"&gt;--open&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What is still missing
&lt;/h2&gt;

&lt;p&gt;A lot.&lt;/p&gt;

&lt;p&gt;This is still pre-1.0 work, and I do not want to fake maturity where it does not exist.&lt;/p&gt;

&lt;p&gt;There is still polish to do. There are still workflow edges to improve. There is still room to make the UX sharper, the docs tighter, and the tool more battle-ready for bigger real-world cases.&lt;/p&gt;

&lt;p&gt;That is exactly why I am sharing it now.&lt;/p&gt;

&lt;p&gt;I like build-in-public when it is honest. Not “look at my perfect tool,” but “here is the problem, here is the current state, here is the direction.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I am posting this now
&lt;/h2&gt;

&lt;p&gt;Because I think Contentful teams deserve better tooling around model design, migration preview, and validation.&lt;/p&gt;

&lt;p&gt;And because I want to contribute something useful to that space while I am still learning from the build itself.&lt;/p&gt;

&lt;p&gt;So this is where the project stands today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;current version:&lt;/strong&gt; &lt;code&gt;v0.3.0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;status:&lt;/strong&gt; still in progress&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;goal:&lt;/strong&gt; &lt;code&gt;v1.0.0&lt;/code&gt; by the end of May&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you work with Contentful and this problem sounds familiar, feel free to take a look, break it, question it, or tell me where the current workflow still feels weak.&lt;/p&gt;

&lt;p&gt;That feedback is more useful to me than fake applause.&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%2Ffokt15lgzi5wiykghkrx.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%2Ffokt15lgzi5wiykghkrx.png" alt="content-model-simulator v0.3.0" width="800" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/JoshuaPozos/content-model-simulator" rel="noopener noreferrer"&gt;github.com/JoshuaPozos/content-model-simulator&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Package:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/content-model-simulator" rel="noopener noreferrer"&gt;npmjs.com/package/content-model-simulator&lt;/a&gt;&lt;/p&gt;

</description>
      <category>contentful</category>
      <category>webdev</category>
      <category>typescript</category>
      <category>devtools</category>
    </item>
    <item>
      <title>GraphQL Server Using NEXT.js and MongoDB Atlas</title>
      <dc:creator>Joshua Pozos</dc:creator>
      <pubDate>Mon, 02 Aug 2021 23:41:17 +0000</pubDate>
      <link>https://dev.to/joshuapozos/graphql-server-using-next-js-and-mongodb-atlas-93i</link>
      <guid>https://dev.to/joshuapozos/graphql-server-using-next-js-and-mongodb-atlas-93i</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;First, sorry if something is not well written, I am still learning English&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Add the following dependencies in your project
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add apollo-server-micro@2.25.1 mongoose graphql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;I used this version of apollo-server-micro because the new version 3 sends you to a sandbox that in my opinion is uncomfortable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the root of your project create a folder with the name you prefer, in this case I use "db". Inside create two more folders, one called "config" and the other "models"&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir db &amp;amp;&amp;amp; cd db &amp;amp;&amp;amp; mkdir config &amp;amp;&amp;amp; mkdir models
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fk3f2fvj66a3gb3qejnj6.jpeg" 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%2Fk3f2fvj66a3gb3qejnj6.jpeg" alt="Alt Text" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Config
&lt;/h3&gt;

&lt;p&gt;Inside the config folder create an index.js file and add "moongose". For the MongoDb uri it is good practice to add it inside an .env file and bring it with proccess.env.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const mongoose = require('mongoose')

const MongoDb = process.env.MONGODB_URI

const connectDb = async () =&amp;gt; {
  try {
    await mongoose.connect(MongoDb, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
      useFindAndModify: false,
      useCreateIndex: true,
    })
    console.log('db success connect')
  } catch (err) {
    console.log('error connecting to database')
    console.log(err)
    process.exit(1)
  }
}

module.exports = connectDb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Models
&lt;/h3&gt;

&lt;p&gt;Now we are going to create an example model, in this case the product model. So inside the "models" folder I create a file called product.js and add moongose and what I need for the model.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import mongoose from 'mongoose'

const { Schema } = mongoose

mongoose.Promise = global.Promise

const ProductsSchema = new Schema({
  name: {
    type: String,
    required: true,
    trim: true,
  },
  productionCapacity: {
    type: Number,
    required: true,
    trim: true,
  },
  price: {
    type: Number,
    required: true,
    trim: true,
  },
  description: {
    type: String,
    trim: true,
  },
  createAt: {
    type: Date,
    defalut: Date.now(),
  },
})

ProductsSchema.index({ name: 'text' })

module.exports =
  mongoose.models.Product || mongoose.model('Product', ProductsSchema)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Schema and resolvers
&lt;/h3&gt;

&lt;p&gt;I'll leave the code here as an example because your project can be totally different.&lt;/p&gt;
&lt;h4&gt;
  
  
  Schema
&lt;/h4&gt;

&lt;p&gt;For the schema we will import &lt;code&gt;gql&lt;/code&gt; from &lt;code&gt;apollo-server-micro&lt;/code&gt; and create a constant called "typeDefs" in which we will use &lt;code&gt;gql&lt;/code&gt; and inside we will define our types, inputs, queries and mutations&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { gql } from 'apollo-server-micro'

const typeDefs = gql`
  # Products
  type Product {
    id: ID
    name: String
    productionCapacity: Int
    price: Float
    description: String
  }

  input ProductInput {
    name: String!
    productionCapacity: Int!
    price: Float!
    description: String
  }

  type Query {
    getProducts: [Product]
    getProduct(id: ID!): Product
  }

  type Mutation {
    #Products
    newProduct(input: ProductInput): Product
    updateProduct(id: ID!, input: ProductInput): Product
    deleteProduct(id: ID!): String
  }
`

module.exports = typeDefs

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Resolvers
&lt;/h4&gt;

&lt;p&gt;I will leave the code that I use, but remember that your project can be very different. We bring the models, in this case I bring my "product" model to be able to use it within the queries or mutations that I define.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Product = require('./models/product')

const resolvers = {
  Query: {
    // products
    getProducts: async () =&amp;gt; {
      try {
        const products = await Product.find({})

        return products
      } catch (err) {
        console.log(err)
      }
    },
    getProduct: async (_, { id }) =&amp;gt; {
      const product = await Product.findById(id)

      if (!product) {
        throw new Error('Product not found')
      }

      return product
    },
  },

  Mutation: {
    // products
    newProduct: async (_, { input }) =&amp;gt; {
      try {
        const product = new Product(input)

        const result = await product.save()

        return result
      } catch (err) {
        console.log(err)
      }
    },
    updateProduct: async (_, { id, input }) =&amp;gt; {
      let product = await Product.findById(id)

      if (!product) {
        throw new Error('Product not found')
      }

      product = await Product.findOneAndUpdate({ _id: id }, input, {
        new: true,
      })

      return product
    },
    deleteProduct: async (_, { id }) =&amp;gt; {
      const product = await Product.findById(id)

      if (!product) {
        throw new Error('Producto no encontrado')
      }

      await Product.findOneAndDelete({ _id: id })

      return 'Producto eliminado'
    },
  },
}

module.exports = resolvers

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Creating the endpoint
&lt;/h3&gt;

&lt;p&gt;First we create a graphql.js file (it can be called whatever) inside /pages/api.&lt;br&gt;
In the graphql.js file we are going to import &lt;code&gt;ApolloServer&lt;/code&gt; and &lt;code&gt;makeExecutableSchema&lt;/code&gt; from &lt;code&gt;apollo-server-micro&lt;/code&gt; and &lt;code&gt;typeDefs&lt;/code&gt;, &lt;code&gt;resolvers&lt;/code&gt; and &lt;code&gt;connectDb&lt;/code&gt; from their corresponding files. Then we run the &lt;code&gt;connectDb()&lt;/code&gt; function and create a schema with &lt;code&gt;makeExecutableSchema&lt;/code&gt; which will have the &lt;code&gt;typeDefs&lt;/code&gt; and the &lt;code&gt;resolvers&lt;/code&gt;.&lt;br&gt;
And at the end we export the Apollo Server passing it our schema variable and defining the path that must match the name of the file that we put in /pages/api.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { ApolloServer, makeExecutableSchema } from 'apollo-server-micro'
import typeDefs from '../../db/schema'
import resolvers from '../../db/resolvers'
import connectDb from '../../db/config'

connectDb()

export const schema = makeExecutableSchema({
  typeDefs,
  resolvers
})

export const config = {
  api: {
    bodyParser: false,
  },
}

export default new ApolloServer({ schema }).createHandler({
  path: '/api/graphql',
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Your project should have been more or less like this&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%2F7vnhwkd6eojebi4ld149.jpeg" 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%2F7vnhwkd6eojebi4ld149.jpeg" alt="Alt Text" width="280" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now run the project and go to the url of your api with graphql&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fl3jccklkxbrobcf3dc46.jpeg" 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%2Fl3jccklkxbrobcf3dc46.jpeg" alt="Alt Text" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I leave the package.json for you to check the version of the dependencies used in this post.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "graphql-nextjs",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "apollo-server-micro": "2.25.1",
    "graphql": "^15.5.1",
    "mongoose": "^5.13.5",
    "next": "11.0.1",
    "react": "17.0.2",
    "react-dom": "17.0.2"
  },
  "devDependencies": {
    "eslint": "7.32.0",
    "eslint-config-next": "11.0.1"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Repo
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/JoshuaPozos" rel="noopener noreferrer"&gt;
        JoshuaPozos
      &lt;/a&gt; / &lt;a href="https://github.com/JoshuaPozos/graphql-nextjs" rel="noopener noreferrer"&gt;
        graphql-nextjs
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;GraphQL Server Using NEXT.js and MongoDB Atlas&lt;/h1&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Setup&lt;/h2&gt;

&lt;/div&gt;

&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;yarn install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Create ur own &lt;code&gt;MONGODB_URI&lt;/code&gt; into .env file (.env.development or .env.local) and add ur mongodb uri.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Ready&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Modify all u need to ur project&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Development mode&lt;/h2&gt;

&lt;/div&gt;

&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;yarn dev
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/JoshuaPozos/graphql-nextjs" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



</description>
      <category>nextjs</category>
      <category>graphql</category>
      <category>mongodb</category>
      <category>react</category>
    </item>
  </channel>
</rss>
