0

I can successfully view my GraphQL query via apollo-graphql-studio: The resolver is correctly configured, but I'm not sure how to render data.

I know that the next-js swr react-hook is performant, so I'd like to fetch data via the swr method:

import useSWR from "swr";

const Query = `
  books {
    title
  }
`;

export default function Home() {
  const fetcher = async () => {
    const response = await fetch("/api/graphql", {
      body: JSON.stringify({ query: Query }),
      headers: { "Content-type": "application/json" },
      method: "POST"
    });
    const { data } = await response.json();
    return data;
  };

  const { data, error } = useSWR([Query], fetcher);

  if (error) return <div>failed to load</div>;
  if (!data) return <div>loading...</div>;
  return (
    <div>
      <div>hello {data?.books?.title}</div>
    </div>
  );
}

This is just returning loading... so the data is clearly not correctly fetched. Although, as I said, I can retrieve it via the Apollo-graphql-studio IDE.

The console error is a 400 Bad Request on the API route: /api/graphql, so this is where the problem is.

How can I render the data?

Here's the GraphQL API:

import Cors from 'micro-cors'
import { gql, ApolloServer } from 'apollo-server-micro'
import { Client, Map, Paginate, Documents, Collection, Lambda, Get } from 'faunadb'

const client = new Client({
    secret: process.env.FAUNA_SECRET,
    domain: "db.fauna.com",
})

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

const typeDefs = gql`
    type Book {
        title: String
        author: String
    }

    type Query {
        books: [Book]
    }
`

const resolvers = {
    Query: {
        books: async () => {
            const response = await client.query(
                Map(
                    Paginate(Documents(Collection('Book'))),
                    Lambda((x) => Get(x))
                )
            )
            const books = response.data.map(item => item.data)
            return [...books]
        },
    },
}
const cors = Cors()

const apolloServer = new ApolloServer({
    typeDefs,
    resolvers,
    context: ({ req }) => {

    },
    introspection: true,
    playground: true,
})

const serversStart = apolloServer.start()

export default cors(async (req, res) => {
    if (req.method === "OPTIONS") {
        res.end();
        return false;
    }

    await serversStart;
    await apolloServer.createHandler({ path: '/api/graphql' })(req, res)
})
WΔ_
  • 1,229
  • 4
  • 20
  • 34
  • 1
    Do you see the request in the dev tools network tab? – juliomalves Oct 29 '21 at 08:47
  • It's throwing a 400 Bad Request so presumably the error is in the fetch request. – WΔ_ Oct 29 '21 at 11:42
  • @juliomalves I added the GraphQL API to the question to clarify the problem. – WΔ_ Oct 29 '21 at 20:22
  • 1
    Shouldn't the field be named `query` (all lowercase) in the body's object, i.e. `body: JSON.stringify({ query: Query })`? – juliomalves Oct 29 '21 at 22:06
  • @juliomalves I updated the code, the error is still occurring earlier, however. With other data fetching methods I'm also running into the same issue. I cannot fetch via the `/api/graphql` route. Basically I'm not sure how you fetch using `apollo-server-micro`, this is a link to the original repo: https://github.com/winterdelta/waves-of-gold. – WΔ_ Oct 30 '21 at 18:23

1 Answers1

1

This is how i do it with Apollo Client:

import { ApolloClient, InMemoryCache, createHttpLink } from "@apollo/client";

const defaultOptions: any = {
  watchQuery: {
    fetchPolicy: "no-cache",
    errorPolicy: "ignore",
  },
  query: {
    fetchPolicy: "no-cache",
    errorPolicy: "all",
  },
};

const cache = new InMemoryCache({
  resultCaching: false,
});


const link = createHttpLink({
  uri: process.env.NEXT_PUBLIC_GRAPQL_URI,
  
});

export const client: any = new ApolloClient({
 
  connectToDevTools: true,
  link,
  cache,
  defaultOptions,
});

then in frontend:

const { data, error } = useSWR(MY_QUERY, query => client.query({ query }));

Should be similar with Apollo Server also

Ilir
  • 488
  • 5
  • 20