# Instant GraphQL APIs for MongoDB with Grafbase

# Instant GraphQL APIs for MongoDB with Grafbase

In the ever-evolving landscape of web development, efficient data management and retrieval are paramount for creating dynamic and responsive applications. MongoDB, a versatile NoSQL database, and GraphQL, a powerful query language for APIs, have emerged as a dynamic duo that empowers developers to build robust, flexible, and high-performance applications.

When combined, MongoDB and GraphQL offer a powerful solution for front-end developers, especially when used at the edge.

You may be curious about the synergy between an unstructured database and a structured query language. Fortunately, Grafbase offers a solution that seamlessly combines both by leveraging its distinctive connector schema transformations.

## Prerequisites

In this tutorial, you’ll see how easy it is to get set up with MongoDB and Grafbase, simplifying the introduction of GraphQL into your applications. 

You will need the following to get started:

- An account with Grafbase
- An account with MongoDB Atlas
- A database with data API access enabled

## Enable data API access

You will need a database with MongoDB Atlas to follow along — create one now!

For the purposes of this tutorial, I’ve created a free shared cluster with a single database deployment. We’ll refer to this instance as your “Data Source” later.

 through the `g.datasource(mongodb)` call.

## Create models for data

The MongoDB connector empowers developers to organize their MongoDB collections in a manner that allows Grafbase to autonomously generate the essential queries and mutations for document creation, retrieval, update, and deletion within these collections.

Within Grafbase, each configuration for a collection is referred to as a "model," and you have the flexibility to employ the supported GraphQL Scalars to represent data within the collection(s).

It's important to consider that in cases where you possess pre-existing documents in your collection, not all fields are applicable to every document.

Let’s work under the assumption that you have no existing documents and want to create a new collection for `users`. Using the Grafbase TypeScript SDK, we can write the schema for each user model. It looks something like this:

```ts
const address = g.type('Address', {
  street: g.string().mapped('street_name')
})

mongodb
  .model('User', {
    name: g.string(),
    email: g.string().optional(),
    address: g.ref(address)
  })
  .collection('users')
```

This schema will generate a fully working GraphQL API with queries and mutations as well as all input types for pagination, ordering, and filtering:

- `userCreate` – Create a new user
- `userCreateMany` – Batch create new users
- `userUpdate` – Update an existing user
- `userUpdateMany` – Batch update users
- `userDelete` – Delete a user
- `userDeleteMany` – Batch delete users
- `user` – Fetch a single user record
- `userCollection` – Fetch multiple users from a collection

MongoDB automatically generates collections when you first store data, so there’s no need to manually create a collection for users at this step.

We’re now ready to start the Grafbase development server using the CLI:

```bash
npx grafbase dev
```

This command runs the entire Grafbase GraphQL API locally that you can use when developing your front end. The Grafbase API communicates directly with your Atlas Data API.

Once the command is running, you’ll be able to visit http://127.0.0.1:4000 and explore the GraphQL API.

## Insert users with GraphQL to MongoDB instance

Let’s test out creating users inside our MongoDB collection using the generated `userCreate` mutation that was provided to us by Grafbase.

Using Pathfinder at http://127.0.0.1:4000, execute the following mutation:

```
mutation {
  mongo {
    userCreate(input: {
      name: "Jamie Barton",
      email: "jamie@grafbase.com",
      age: 40
    }) {
      insertedId
    }
  }
}
```

If everything is hooked up correctly, you should see a response that looks something like this:

```json
{
  "data": {
    "mongo": {
      "userCreate": {
        "insertedId": "65154a3d4ddec953105be188"
      }
    }
  }
}
```

You should repeat this step a few times to create multiple users.

## Update user by ID

Now we’ve created some users in our MongoDB collection, let’s try updating a user by `insertedId`:

```
mutation {
  mongo {
    userUpdate(by: {
      id: "65154a3d4ddec953105be188"
    }, input: {
      age: {
        set: 35
      }
    }) {
      modifiedCount
    }
  }
}
```

Using the `userUpdate` mutation above, we `set` a new `age` value for the user where the `id` matches that of the ObjectID we passed in.

If everything was successful, you should see something like this:

```json
{
  "data": {
    "mongo": {
      "userUpdate": {
        "modifiedCount": 1
      }
    }
  }
}
```

## Delete user by ID

Deleting users is similar to the create and update mutations above, but we don’t need to provide any additional `input` data since we’re deleting only:

```
mutation {
  mongo {
    userDelete(by: {
      id: "65154a3d4ddec953105be188"
    }) {
      deletedCount
    }
  }
}
```

If everything was successful, you should see something like this:

```json
{
  "data": {
    "mongo": {
      "userDelete": {
        "deletedCount": 1
      }
    }
  }
}
```

## Fetch all users

Grafbase generates the query `userCollection` that you can use to fetch all users. Grafbase requires a `first` or `last` pagination value with a max value of `100`:

```
query {
  mongo {
    userCollection(first: 100) {
      edges {
        node {
          id
          name
          email
          age
        }
      }
    }
  }
}
```

Here we are fetching the `first` 100 users from the collection. You can also pass a filter and order argument to tune the results:

```
query {
  mongo {
    userCollection(first: 100, filter: {
      age: {
        gt: 30
      }
    }, orderBy: {
      age: ASC
    }) {
      edges {
        node {
          id
          name
          email
          age
        }
      }
    }
  }
}
```

## Fetch user by ID

Using the same GraphQL API, we can fetch a user by the object ID. Grafbase automatically generates the query `user` where we can pass the `id` to the `by` input type:

```
query {
  mongo {
    user(
      by: {
        id: "64ee1cfbb315482287acea78"
      }
    ) {
      id
      name
      email
      age
    }
  }
}
```

## Enable faster responses with GraphQL Edge Caching

Every request we make so far to our GraphQL API makes a round trip to the MongoDB database. This is fine, but we can improve response times even further by enabling GraphQL Edge Caching for GraphQL queries.

To enable GraphQL Edge Caching, inside `grafbase/grafbase.config.ts`, add the following to the `config` export:

```ts
export default config({
  schema: g,
  cache: {
    rules: 
      {
        types: 'Query',
        maxAge: 60
      }
    ]
  }
})
```

This configuration will cache any query. If you only want to disable caching on some collections, you can do that too. [Learn more about GraphQL Edge Caching.

## Deploy to the edge

So far, we’ve been working with Grafbase locally using the CLI, but now it’s time to deploy this around the world to the edge with GitHub.

If you already have an existing GitHub repository, go ahead and commit the changes we’ve made so far. If you don’t already have a GitHub repository, you will need to create one, commit this code, and push it to GitHub.

Now, create a new project with Grafbase and connect your GitHub account. You’ll need to permit Grafbase to read your repository contents, so make sure you select the correct repository and allow that.

Before you click **Deploy**, make sure to insert the environment variables obtained previously in the tutorial. Grafbase also supports environment variables for preview environments, so if you want to use a different MongoDB database for any Grafbase preview deployment, you can configure that later.

, URQL, and Houdini.

If you have questions or comments, continue the conversation over in the MongoDB Developer Community.

  [1]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/blt86a1fb09aa5e51ae/65282bf00749064f73257e71/image6.png
  [2]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/blt67f4040e41799bbc/65282c10814c6c262bc93103/image1.png
  [3]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/blt75ca38cd9261e241/65282c30ff3bbd5d44ad0aa3/image4.png
  [4]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/bltaf2a2af39e731dbe/65282c54391807638d3b0e1d/image5.png
  [5]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/blt0c9563b3fdbf34fd/65282c794824f57358f273cf/image3.png
  [6]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/blt731c99011d158491/65282ca631f9bbb92a9669ad/image2.png