전체 글

개 발 자 로 살 아 남 기
· TIL
실전적 Apollo Client 구현기1. 문제 상황기술 스택Next.js 15 (App Router)Hasura GraphQLApollo Client with @apollo/client-integration-nextjs해결해야 했던 문제들중복 코드 문제: 서버용, 어드민용, 클라이언트용 총 3개의 Apollo Client 인스턴스가 필요했는데, 각각에 대해 Apollo Links를 별도로 작성하면 코드 중복이 심각함서버/클라이언트 경계 처리: RSC(React Server Components) 환경에서 서버와 클라이언트의 인증 방식이 달라 각각 다른 처리가 필요토큰 갱신 로직: 클라이언트에서만 토큰 갱신이 가능하므로 환경별로 다른 에러 처리 필요2. 해결 방안: 팩토리 패턴과 의존성 주입2.1 팩토리 ..
· TIL
Hasura(GQL) 사용시 3rd-Party 쿠키 정책 문제Q) credentials: "include" 인데도 쿠키 자동 전송 안될 수 있는거 맞음?제가 cookie 기반에서 httponly, secured, domain, samesite 설명을 여러가지로 변주해서 시도해봤지만 결론은 브라우저의 third-party cookie 정책으로 인해 쿠키가 자동 전송되지 않는데 이게 맞나요?(심지어 서브도메인 - api.myapp.com myapp.com 이더라도)A) 맞다.맞아요. 결론부터 말하면: 브라우저가 Hasura로 쿠키를 보내주지 못하면(3rd‑party 쿠키 차단), Remote Schema를 써도 Hasura가 JWT를 검증할 수 없고, 따라서 x-hasura-user-id 같은 세션 변수도..
· TIL
Server 용 Apollo Client 생성시 주의점!TL; DRregisterApolloClient는 싱글톤처럼 동작하지만, getToken을 함수로 전달하면 매 요청마다 토큰을 새로 읽어와서 안전할 수 있음. 참고하지만 캐시 오염 가능성은 여전히 존재하므로, 민감한 데이터는 fetchPolicy: 'no-cache' 사용을 권장.getToken 없이 credentials: 'include'만으로는 절대 작동하지 않음!가장 안전한 방법은 요청별 클라이언트를 생성하는 것이지만, getToken을 올바르게 구현하면 registerApolloClient만으로 충분히 사용 가능.코드 예시// /lib/apollo/server.tsimport { Defer20220824Handler } from "@apoll..
· TIL
GraphQL Yoga 역할(+Hasura Remote Schema)예시// /api/graphql/route.tsimport { DateTimeTypeDefinition } from "graphql-scalars";import { createSchema, createYoga } from "graphql-yoga";import { v4 as uuid } from "uuid";interface NextContext { params: Promise>;}const typeDefs = /* GraphQL */ ` type Query { session: Session! } type Mutation { ok: String! } type Session { ..
· TIL
Next.js 15 테스트 환경 구축 가이드0단계: 조합유닛테스트: Vitest통합테스트: React Testing Library + MSWE2E테스트: Playwright1단계: 테스트 환경 구축1️⃣ Vitest 설정 (유닛 테스트)pnpm add -D vitest @vitejs/plugin-react jsdompnpm add -D @testing-library/react @testing-library/jest-dom @testing-library/user-eventvitest.config.tsimport { defineConfig } from 'vitest/config'import react from '@vitejs/plugin-react'import path from 'path'export def..
· TIL
0. 아래와 같은 Auth.js 기본 세팅 + apollo 세팅은 되어있다는 가정// lib/auth.tsimport NextAuth from "next-auth";import Google from "next-auth/providers/google";import { HasuraAdapter } from "@auth/hasura-adapter";import { JWT } from "next-auth/jwt";declare module "next-auth/jwt" { interface JWT { id: string; role: string; } }export const { handlers, signIn, signOut, auth } = NextAuth({ adap..
· TIL
React Query에서 클래스 메서드를 queryFn으로 사용할 때 주의사항문제 상황React Query를 사용하다가 다음과 같은 에러를 만났습니다:Cannot read properties of undefined (reading 'get')코드는 다음과 같았습니다:// queries.tsexport const useUserQuery = () => { return useQuery({ queryKey: ['user'], queryFn: api.getUser, // 이 부분이 문제! });};// apis.tsclass ApiClient extends BaseApiClient { public getUser() { return this.get("/api/auth/user"); }}기본적..
· TIL
Hasura 트랜잭션 처리: Actions와 Functions 활용하기📌 TL;DR (한 줄 요약)Hasura v2는 단일 mutation 내부는 자동 트랜잭션이지만,복잡한 로직은 Actions 또는 PostgreSQL Functions로 처리해야 합니다.🎯 핵심 정리단일 GraphQL mutation은 자동으로 트랜잭션 처리여러 mutation을 별도 호출하면 트랜잭션 아님Hasura Actions로 커스텀 비즈니스 로직 구현 (추천)PostgreSQL Functions (RPC)로 DB 레벨 트랜잭션 처리Apollo Client의 배치는 서버 트랜잭션이 아님1. Hasura의 트랜잭션 동작 방식✅ 자동 트랜잭션 (보장됨)# 하나의 mutation 요청 = 하나의 트랜잭션mutation Create..
· TIL
PostgREST와 Hasura의 관계Hasura는 PostgREST를 사용하지 않습니다.Hasura와 PostgREST는 완전히 별개의 프로젝트!차이점 비교아키텍처Supabase:PostgreSQL → PostgREST → REST API → Supabase JS ClientHasura:PostgreSQL → Hasura Engine → GraphQL API → Apollo Client기술 스택 SupabaseHasura프로토콜REST (PostgREST 사용)GraphQL (자체 엔진)쿼리 언어URL + 체이닝GraphQL엔진PostgREST (Haskell)Hasura Engine (Haskell)철학REST + GraphQL 스타일 쿼리순수 GraphQL참고 블로그 글의 의미PostgREST? "..
· library
Supabase의 PostgREST: GraphQL처럼 쿼리하는 SQL📌 TL;DR (한 줄 요약)Supabase는 PostgREST를 통해 GraphQL의 선언적 쿼리 스타일을 REST API로 구현하여, SQL JOIN을 직관적인 체이닝 메서드로 사용할 수 있게 합니다.🎯 핵심 정리Supabase JS는 SQL을 직접 쓰지 않고 체이닝 메서드 사용PostgREST는 GraphQL의 장점과 REST의 단순함을 결합한 프로토콜Foreign Key 기반으로 자동 관계 생성 - 별도 설정 불필요중첩 쿼리로 복잡한 JOIN도 간단하게 표현TypeScript 타입 자동 생성으로 완벽한 타입 안정성1. SQL JOIN의 전통적 방식전통적인 SQL JOIN-- 게시글 + 작성자 정보SELECT posts.i..
adminisme
elseif