Nick Truby
Nick Truby

Reputation: 41

API Routes on Next.JS with Apollo-Server : why does using a basePath cause error?

I'm using API Routes on a Next.JS app with Apollo-Server, to create a GraphQL API wrapper around a REST endpoint. But I'm running into an issue if the project has a bathPath.

I've been following this example, and a video tutorial on youtube. I've replicated my issue by using the repo from that tutorial. Upon running that code $ yarn dev, and navigating to http://localhost:3000/api/graphql the GraphQl playground shows up, and works as expected.

However if I add a basepath to the project then the graphQl playground still shows up fine at http://localhost:300/basepath/api/graphql but it gives me the error of "Server cannot be reached" and shows a 404 error in the network tab on the dev tools.

To add the base path I created a next.config.js and added

module.exports = {
   basePath: '/basepath'
}

In pages/api/graphql.ts I updated the path from /api/graphql to /basepath/api/graphql

import { ApolloServer } from "apollo-server-micro";
import { schema } from "src/schema";

const server = new ApolloServer({ schema });
const handler = server.createHandler({ path: "/somewhere/api/graphql" });

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

export default handler;

In src/apollo.ts I updated the HttpLink uri from /api/graphql to /basepath/api/graphql

import {
  ApolloClient,
  InMemoryCache,
  NormalizedCacheObject,
} from "@apollo/client";
import { useMemo } from "react";

let apolloClient: ApolloClient<NormalizedCacheObject>;

function createIsomorphicLink() {
  if (typeof window === "undefined") {
    // server
    const { SchemaLink } = require("@apollo/client/link/schema");
    const { schema } = require("./schema");
    return new SchemaLink({ schema });
  } else {
    // client
    const { HttpLink } = require("@apollo/client/link/http");
    return new HttpLink({ uri: "/bathpath/api/graphql" });
  }
}

function createApolloClient() {
  return new ApolloClient({
    ssrMode: typeof window === "undefined",
    link: createIsomorphicLink(),
    cache: new InMemoryCache(),
  });
}

export function initializeApollo(initialState = null) {
  const _apolloClient = apolloClient ?? createApolloClient();

  if (initialState) {
    _apolloClient.cache.restore(initialState);
  }

  if (typeof window === "undefined") return _apolloClient;
  apolloClient = apolloClient ?? _apolloClient;

  return apolloClient;
}

export function useApollo(initialState) {
  const store = useMemo(() => initializeApollo(initialState), [initialState]);
  return store;
}

Any ideas why adding a basepath would break this setup? and what I'd need to do to fix it?

This is my first time posting on stack overflow, so I hope my description is good enough, please do ask if I've missed anything and thanks for your help in advance!

Upvotes: 4

Views: 707

Answers (1)

rotato poti
rotato poti

Reputation: 131

Your apollo variable will now be the url with the basepath. you need to set up a new apollo variable as an environment variable without it. Then go into apollo and request that variable instead of the BASE_URL. In my case the file was src/apollo/client.js . You will see something like process.env.BASE_URL

Change that to process.env.APOLLO_URL after creating the env variable which in my case I created in an env.local file.

Upvotes: 0

Related Questions