전체 글

개 발 자 로 살 아 남 기
· TIL
PostgREST vs GraphQL(Hasura): 현실적인 기술 스택 비교PostgreSQL을 사용하는 프로젝트에서 API 레이어를 구성할 때, 두 가지 옵션을 비교해봤습니다.이 비교는 GraphQL이 정말 필요한 상황은 언제인가? 에 대해서 생각해보다가 시작하게 되었습니다. GraphQL + Hasura + codegen 의 강력함은 프로젝트를 해보면서 알게 되었는데다만 PostgREST 에서도 유연한 쿼리, 관계 기반 페칭이 잘 되므로(supabase.js 에서 보듯...) 요구사항만 맞는다면 Hasura 혹은 resolver 구성에 드는 비용을 줄이면서도GraphQL의 이점을 유사하게 구사할 수 있을 것 같았습니다. 그래서 GraphQL + Hasura 에 대항할 수 있는 REST 스펙을 아래와..
· TIL
naver 로그인 구현 with Supabase 3편TL; DR: admin 권한 쓰면 끝작년 7월에 supabase에서 편법(?) naver 로그인 기능을 구현했었습니다.1년 넘게 지났는데 갑자기 편법 말고 진짜로 구현이 되겠잖아? 생각이 들었어요. supabase 어드민 권한을 쓰면 auth 스키마에도 입력이 될 것 같았고해봤더니 역시 아주 잘 되었습니다... 이 생각을 왜 작년엔 못했을까요? 한가지 문제는 네이버 OAuth 를 프로덕션으로 쓰려면네이버 개발자센터 > 내 애플리케이션 > 네이버 로그인 검수 상태에서 검수가 완료되어야 합니다. 검수가이드 보면 대단한 걸 요구하는건 아닌데 귀찮습니다.카카오는 검수 없이도 기본적인 정보들은 그냥 받을 수 있는데네이버는 아무튼간 안되는 것 같습니다. 결론은,..
· TIL
🍪 Cookie, CORS, Site/Origin 총정리1. TL;DRexample.com(프론트엔드)에서 api.example.com(백엔드)으로 인증 요청을 보낼 때:Same-Site이지만 Cross-Origin입니다쿠키에 domain: ".example.com" 설정 필요sameSite: "lax" 충분 (Cross-Site 아니므로)백엔드 CORS 설정 필수 (별개 정책!)Apollo Client 등 라이브러리 credentials: "include" 필수핵심: 쿠키 정책(브라우저)과 CORS(서버) 둘 다 맞춰야 성공..2. Site vs Origin 개념📚 정의Origin = Protocol + Domain + Port (모두 일치해야 Same-Origin)Site = 루트 도메인(eTLD..
· 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"); }}기본적..
adminisme
elseif