31
loading...
This website collects cookies to deliver better user experience
Note: As of Redwood v0.37, GraphQL Helix and Envelop are included by default in the Redwood API instead of Apollo Server.
If you are on v0.37 or later than you will not need the instructions in this article or the instructions in the official migration guide, Using GraphQL Envelop+Helix in Redwood v0.35+.
These instructions are only needed when upgrading from an older version of Redwood. This article is now mostly relevant as a historical snapshot of the development of the framework.
Hi, people of the Redwood! :)
I created an initial PR for migrating from apollo-server-lambda to Envelop and GraphQL-Helix. The goal of this PR is to normalize the incoming HTTP requests and try to handle them in a generic way. Also, since the request is detached from the handler, we can use any GraphQL library for execution.
While graphql-helix
provides the basic pipeline and the initial request normalization, envelop
provides the connection to the GraphQL execution, and allow to enrich the entire GraphQL execution pipeline with custom code (custom context building, parser cache, validation cache, tracing, metrics collection and more).
Dotan Simha - Partial normalization of Lambda request (April 25, 2021)
Earlier this week I released GraphQL Helix, a new JavaScript library that lets you take charge of your GraphQL server implementation.
There's a couple of factors that pushed me to roll my own GraphQL server library:
@defer
, @stream
and @live
directives.Unfortunately, popular solutions like Apollo Server, express-graphql and Mercurius fell short in one or more of these regards, so here we are.
Daniel Rearden - Building a GraphQL server with GraphQL Helix (November 5, 2020)
yarn create redwood-app redwood-envelop
cd redwood-envelop
schema.prisma
in api/db
and add the following schema.datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
binaryTargets = "native"
}
model Post {
id Int @id @default(autoincrement())
title String
body String
createdAt DateTime @default(now())
}
railway login
railway init
railway add
DATABASE_URL
inside your .env
file.echo DATABASE_URL=`railway variables get DATABASE_URL` > .env
yarn rw prisma migrate dev
generates the folders and files necessary to create a new migration. We will name our migration posts-table
.yarn rw prisma migrate dev --name posts-table
yarn rw g scaffold post
yarn rw dev
http://localhost:8910/posts
to create a couple blog posts.useEnvelop=true
to the [experimental]
section in your redwood.toml
config. This lets the dev-server
know how to handle the response.[web]
port = 8910
apiProxyPath = "/.redwood/functions"
[api]
port = 8911
[browser]
open = true
[experimental]
esbuild = false
useEnvelop = true
yarn workspace api add @redwoodjs/graphql-server
// api/src/lib/logger.js
import { createLogger } from '@redwoodjs/graphql-server/logger'
export const logger = createLogger({
options: { level: 'info', prettyPrint: true },
})
// api/src/functions/graphql.js
import {
createGraphQLHandler,
makeMergedSchema,
makeServices,
} from '@redwoodjs/graphql-server'
import schemas from 'src/graphql/**/*.{js,ts}'
import { db } from 'src/lib/db'
import { logger } from 'src/lib/logger'
import services from 'src/services/**/*.{js,ts}'
export const handler = createGraphQLHandler({
loggerConfig: {
logger,
options: {
operationName: true,
tracing: true
}
},
schema: makeMergedSchema({
schemas,
services: makeServices({ services }),
}),
onException: () => {
db.$disconnect()
},
})
createGraphQLHandler
configuration options in extraPlugins
. extraPlugins
accepts an array of plugins.'@envelop/depth-limit'
'@envelop/disable-introspection'
'@envelop/filter-operation-type'
'@envelop/parser-cache'
'@envelop/validation-cache'
'@envelop/use-masked-errors'
graphql-server
package if your services raise any errors based on ApolloError
such as UserInputError
or ValidationError
.import { UserInputError } from '@redwoodjs/graphql-server'
@redwoodjs/api
imports in your project make sure to change them to @redwoodjs/graphql-server
.yarn rw dev
yarn rw g page home /
yarn rw g cell posts
// web/src/components/PostsCell/PostsCell.js
export const QUERY = gql`
query PostsQuery {
posts {
id
title
body
createdAt
}
}
`
export const Loading = () => <div>Almost there...</div>
export const Empty = () => <div>WHERE'S THE POSTS?</div>
export const Failure = ({ error }) => <div>{error.message}</div>
export const Success = ({ posts }) => {
return posts.map((post) => (
<article key={post.id}>
<header>
<h2>{post.title}</h2>
</header>
<p>{post.body}</p>
<div>{post.createdAt}</div>
</article>
))
}
// web/src/pages/HomePage/HomePage.js
import PostsCell from 'src/components/PostsCell'
const HomePage = () => {
return (
<>
<h1>Redwood+Envelop</h1>
<PostsCell />
</>
)
}
export default HomePage
yarn rw setup deploy netlify
git init
git add .
git commit -m "the guilded age of redwood"
git remote add origin https://github.com/ajcwebdev/redwood-envelop.git
git push -u origin main
DATABASE_URL
environment variable and add ?connection_limit=1
to the end of the connection string. You can also give your site a custom domain such as redwood-envelop
.query getPosts {
posts {
id
title
body
createdAt
}
}
web
side and Apollo Server on the api
side. These two libraries were fundamental to the development of not only Redwood but the entire GraphQL ecosystem. Apollo itself was born from the ashes of the Meteor Development Group.