Episode 27 mengintegrasikan GraphQL dengan Next.js: API routes dengan Apollo Server, Server-Side Rendering dengan getServerSideProps dan hydration, Static Site Generation dengan getStaticProps dan ISR, App Router dengan Server Components, autentikasi dengan cookies dan NextAuth, hingga deployment ke Vercel.

Next.js adalah framework React paling populer untuk full-stack — dan kombinasi dengan GraphQL sangat natural. Episode 27 mengintegrasikan keduanya secara menyeluruh, dari sisi server sampai strategi rendering. Kita akan membangun GraphQL API route, menerapkan SSR dan SSG, menjelajahi App Router dengan Server Components, membahas autentikasi dengan cookies, dan menutup dengan deployment ke Vercel.
Untuk mengekspos GraphQL sebagai API route Next.js, install npm install @apollo/server @as-integrations/next, lalu gunakan integrasi @as-integrations/next:
import { ApolloServer } from "@apollo/server";
import { startServerAndCreateNextHandler } from "@as-integrations/next";
const server = new ApolloServer({
typeDefs: `type Query { hello: String }`,
resolvers: {
Query: { hello: () => "Halo dari Next.js" },
},
});
const handler = startServerAndCreateNextHandler(server);
export { handler as GET, handler as POST };Simpan file ini sebagai app/api/graphql/route.ts, dan endpoint GraphQL tersedia di /api/graphql. Perhatikan: handler bisa di-export sebagai GET dan POST sekaligus.
API route Next.js berjalan sebagai serverless function. Konsekuensinya: instance server bisa "tidur" dan di-restart (cold start), dan koneksi database tidak boleh dibuat di global scope yang memunculkan terlalu banyak koneksi. Gunakan connection pooling (episode 37) dan hindari state di dalam memori antar request.
import { ApolloClient, InMemoryCache, createHttpLink } from "@apollo/client";
export async function getServerSideProps({ params }) {
const client = new ApolloClient({
ssrMode: true,
link: createHttpLink({ uri: process.env.GRAPHQL_URL }),
cache: new InMemoryCache(),
});
await client.query({
query: GET_USER,
variables: { id: params.id },
});
return {
props: { apolloState: client.extract(), id: params.id },
};
}Pola ssrMode: true dan client.extract() penting: setelah query selesai di server, state cache diekstrak dan dikirim sebagai props, lalu di-hydrate di client. Dengan begitu browser tidak perlu melakukan query ulang dan data tidak berkedip.
Setelah SSR, client dibangun dengan initialState dari cache server agar hasil render server dan client konsisten. Apollo Client menyediakan getDataFromTree untuk mengumpulkan seluruh query pada render server — detail setup ini sudah disediakan pola @apollo/client dengan getDataFromTree untuk React.
export async function getStaticProps() {
const client = createApolloClient();
await client.query({ query: GET_POSTS });
return { props: { apolloState: client.extract() } };
}Dengan Incremental Static Regeneration (ISR), halaman statis bisa di-revalidate berkala. Halaman diregenerasi di background maksimal setiap 60 detik saat ada permintaan baru. On-demand revalidation bahkan memungkinkan memicu regenerasi lewat API atau webhook — cocok setelah mutation GraphQL mengubah konten.
Next.js App Router memperkenalkan Server Components yang bisa fetch data langsung dari GraphQL tanpa client-side state:
export const revalidate = 60;
export default async function HomePage() {
const data = await fetch(process.env.GRAPHQL_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ query: "{ posts { id title } }" }),
next: { revalidate: 60 },
}).then((r) => r.json());
return (
<main>
{data.data.posts.map((post) => (
<PostCard key={post.id} title={post.title} />
))}
</main>
);
}Untuk mutasi dan interaksi, komponen yang butuh state client ditandai "use client" dan memakai hook Apollo atau library fetch biasa. Kombinasi Server Components untuk membaca data dan Client Components untuk menulis data adalah pola dominan di Next.js modern.
Untuk autentikasi full-stack di Next.js:
httpOnly saat login, baca di middleware untuk melindungi route.import { NextResponse } from "next/server";
export function middleware(request) {
const token = request.cookies.get("token");
if (!token) return NextResponse.redirect(new URL("/login", request.url));
return NextResponse.next();
}
export const config = { matcher: ["/dashboard/:path*"] };Detail pola refresh token dan NextAuth akan dikombinasikan dengan GraphQL context di episode 43 untuk multi-tenant.
Hal yang perlu diperhatikan: simpan semua secret (GRAPHQL_URL, JWT_SECRET, database URL) di Vercel Environment Variables, jangan di kode. Optimasi serverless: jaga bundle tetap kecil, gunakan connection pooling untuk database, dan pindahkan tugas berat (image processing, cron) ke fungsi terpisah.
Inti yang harus dibawa pulang:
@as-integrations/next mengekspos endpoint di /api/graphql.ssrMode dan extract menghindari render ganda dan flicker.Di episode 28 selanjutnya kalian akan mempelajari GraphQL dengan mobile development — Apollo Client di React Native, persistensi cache dengan AsyncStorage, arsitektur offline-first dengan antrean mutation, optimasi performa mobile, hingga integrasi Flutter dengan graphql_flutter. GraphQL kalian akan merambah dunia mobile!