Working with Remix Actions and GraphQL

Working with Remix Actions and GraphQL

Remix is a full stack web framework where data is rendered on the server for the client, adhering to web standards. Use Remix for a slick and resilient developer experience!

Let's walk through adding a Remix Action into a project that uses a Form to send messages as a GraphQL mutation to a Grafbase backend. Check out the guide for using a Remix loader for fetching from the same database.

To follow along, have these things installed:

  • Node.js version (^14.17.0, or >=16.0.0)
  • npm 7 or greater
npx create-remix@latest your-project-name

This is followed with prompts to install needed packages like create-remix, and What type of app do you want to create?, with this guide selecting Just the basics.

The next few prompts ask where to deploy and typescript or javascript. This example uses Remix App Server to deploy, and Typescript, completing the installation with npm install

After choosing the default options and installing packages, it is ready for development!

Navigate to the new Remix project

cd your-project-name

View the default application by running npm run dev and browsing localhost:3000

Create a GraphQL backend by initializing Grafbase with

npx grafbase@latest init

This generates a file grafbase/schema.graphql in the project root folder.

Open the schema.graphql file and replace the contents with

type Message @model {
  author: String!
  body: String!
}

Start Grafbase locally with a command and navigate to localhost:4000

npx grafbase@latest dev

The form submission will be handled by a Remix action to send a POST request to the database.

export default function Index() {
  return (
    <main>
      <h3>Grafbase Messages</h3>
      <ul>
        <li>
          <Form method="post">
            <input type="text" name="author" /> {''}
            <input type="text" name="body" /> {''}
            <button type="submit">Add</button>
          </Form>
        </li>
      </ul>
    </main>
  )
}

We will send the form's input as variables in this GraphQL mutation, which is defined before the action function

const MessageCreate = /* GraphQL */ `
  mutation MessageCreate($author: String!, $body: String!) {
    messageCreate(input: { author: $author, body: $body }) {
      message {
        id
      }
    }
  }
`

The action for the form sends a request with the input variables and the database is updated!

export async function action({ request }: { request: any }) {
  const formData = await request.formData()
  let author = formData.get('author')
  let body = formData.get('body')

  const response = await fetch('localhost:4000/graphql', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      query: MessageCreate,
      variables: {
        author,
        body,
      },
    }),
  })

  return await response.json()
}

Get Started

Start building your backend of the future now.