dblock
August 25, 2020, 3:59pm
1
I have an app that gets some restaurant data given a zip.
import { Link, routes } from '@redwoodjs/router'
import { useState } from 'react'
import { Form, TextField, Submit } from '@redwoodjs/forms'
import { GraphQLClient } from 'graphql-request'
export const getZipData = async (zip) => {
const endpoint = `https://....appsync-api.us-east-1.amazonaws.com/graphql`
const graphQLClient = new GraphQLClient(endpoint, {
headers: {
'x-api-key': '...',
},
})
const query = gql`query GetZip($zip: String!) {
get_zip(zip: $zip) {
zip
timezone
restaurants {
name
}
}
}`
return graphQLClient.request(query, { zip: zip })
}
const HomePage = () => {
const [zip, setZip] = useState()
const onSubmit = (data) => {
getZipData(data.zip).then(rc => {
setZip(rc.get_zip)
})
}
return (
<div>
<Form onSubmit={onSubmit} style={{fontSize: '2rem'}}>
<TextField
name="zip"
placeholder="Zip code"
maxLength="5"
validation={{ required: true, pattern: /^\d{5}$/ }}
/>
<Submit>Go</Submit>
</Form>
<div>
{zip &&
<div>
<h2>{zip.zip}</h2>
<h3>{zip.timezone}</h3>
</div>
}
{zip && zip.restaurants.map(r =>
<div>{r.name}</div>
)}
</div>
</div>
)
}
export default HomePage
What I’d like is to turn it into ZipCell that fetches data. How does one turn this into an SDL?
Hi @dblock ! Given that you already have the code above, setting this up on the API side with Service + SDL code should be pretty efficient. Take a look at the “Using a 3rd Party API” Cookbook — specifically the “Server Side API” section:
An opinionated Javascript framework that combines React, GraphQL, Prisma2, SQL, and lots more out of the box.
Let us know how that goes and definitely loop back if you can’t get things to work.
1 Like
Here’s how I wired up Fauna for GraphQL, should be fairly similar to what you’ve got going on here:
Cell
// web/src/components/PostsCell/PostsCell.js
export const QUERY = gql`
query POSTS {
posts {
data {
title
}
}
}
`
export const Loading = () => <div>Loading posts...</div>
export const Empty = () => <div>No posts yet!</div>
export const Failure = ({ error }) => <div>Error: {error.message}</div>
export const Success = ({ posts }) => {
const {data} = posts
return (
<ul>
{data.map(post => (
<li>{post.title}</li>
))}
</ul>
)
}
Page
// web/src/pages/HomePage/HomePage.js
import PostsCell from 'src/components/PostsCell'
const HomePage = () => {
return (
<>
<h1>RedwoodJS+Fauna</h1>
<PostsCell />
</>
)
}
export default HomePage
SDL
// api/src/graphql/posts.sdl.js
import gql from 'graphql-tag'
export const schema = gql`
type Post {
title: String
}
type PostPage {
data: [Post]
}
type Query {
posts: PostPage
}
`
DB
// api/src/lib/db.js
import { GraphQLClient } from 'graphql-request'
export const request = async (query = {}) => {
const endpoint = 'https://graphql.fauna.com/graphql'
const graphQLClient = new GraphQLClient(endpoint, {
headers: {
authorization: 'Bearer <FAUNADB_KEY>'
},
})
try {
return await graphQLClient.request(query)
} catch (error) {
console.log(error)
return error
}
}
Service
// api/src/services/posts/posts.js
import { request } from 'src/lib/db'
import { gql } from 'graphql-request'
export const posts = async () => {
const query = gql`
{
posts {
data {
title
}
}
}
`
const data = await request(query, 'https://graphql.fauna.com/graphql')
return data['posts']
}
GraphQL Handler
// api/src/functions/graphql.js
import {
createGraphQLHandler,
makeMergedSchema,
makeServices,
} from '@redwoodjs/api'
import schemas from 'src/graphql/**/*.{js,ts}'
import services from 'src/services/**/*.{js,ts}'
import { db } from 'src/lib/db'
export const handler = createGraphQLHandler({
schema: makeMergedSchema({
schemas,
services: makeServices({ services }),
}),
db,
})
3 Likes
dom
August 26, 2020, 5:08pm
4
@ajcwebdev This is a really great example! Bookmarking so I’ll be able to direct people here as needed
dblock
August 26, 2020, 7:41pm
5
Very cool, I’ve been hearing a lot about AppSync recently and have been interested in checking it out so this is perfect.