Skip to main content

graphql-schema

GraphQL queries, mutations, and code generation patterns. Use when creating GraphQL operations, working with Apollo Client, or generating types.

소스 정보

저장소
ChrisWiles/claude-code-showcase
최근 소스 활동
2026년 1월 6일 18:50
감지된 SKILL.md 언어
영어
스타
6,071
포크
576

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
graphql-schema
description
GraphQL queries, mutations, and code generation patterns. Use when creating GraphQL operations, working with Apollo Client, or generating types.
# GraphQL Schema Patterns ## Core Rules 1. **NEVER inline `gql` literals** - Create `.gql` files 2. **ALWAYS run codegen** after creating/modifying `.gql` files 3. **ALWAYS add `onError` handler** to mutations 4. **Use generated hooks** - Never write raw Apollo hooks ## File Structure ``` src/ ├── components/ │ └── ItemList/ │ ├── ItemList.tsx │ ├── GetItems.gql # Query definition │ └── GetItems.generated.ts # Auto-generated (don't edit) └── graphql/ └── mutations/ └── CreateItem.gql # Shared mutations ``` ## Creating a Query ### Step 1: Create .gql file ```graphql # src/components/ItemList/GetItems.gql query GetItems($limit: Int, $offset: Int) { items(limit: $limit, offset: $offset) { id name description createdAt } } ``` ### Step 2: Run codegen ```bash npm run gql:typegen ``` ### Step 3: Import and use generated hook ```typescript import { useGetItemsQuery } from './GetItems.generated'; const ItemList = () => { const { data, loading, error, refetch } = useGetItemsQuery({ variables: { limit: 20, offset: 0 }, }); if (error) return <ErrorState error={error} onRetry={refetch} />; if (loading && !data) return <LoadingSkeleton />; if (!data?.items.length) return <EmptyState />; return <List items={data.items} />; }; ``` ## Creating a Mutation ### Step 1: Create .gql file ```graphql # src/graphql/mutations/CreateItem.gql mutation CreateItem($input: CreateItemInput!) { createItem(input: $input) { id name description } } ``` ### Step 2: Run codegen ```bash npm run gql:typegen ``` ### Step 3: Use with REQUIRED error handling ```typescript import { useCreateItemMutation } from 'graphql/mutations/CreateItem.generated'; const CreateItemForm = () => { const [createItem, { loading }] = useCreateItemMutation({ // Success handling onCompleted: (data) => { toast.success({ title: 'Item created' }); navigation.goBack(); }, // ERROR HANDLING IS REQUIRED onError: (error) => { console.error('createItem failed:', error); toast.error({ title: 'Failed to create item' }); }, // Cache update update: (cache, { data }) => { if (data?.createItem) { cache.modify({ fields: { items: (existing = []) => [...existing, data.createItem], }, }); } }, }); return ( <Button onPress={() => createItem({ variables: { input: formValues } })} isDisabled={!isValid || loading} isLoading={loading} > Create </Button> ); }; ``` ## Mutation UI Requirements **CRITICAL: Every mutation trigger must:** 1. **Be disabled during mutation** - Prevent double-clicks 2. **Show loading state** - Visual feedback 3. **Have onError handler** - User knows it failed 4. **Show success feedback** - User knows it worked ```typescript // CORRECT - Complete mutation pattern const [submit, { loading }] = useSubmitMutation({ onError: (error) => { console.error('submit failed:', error); toast.error({ title: 'Save failed' }); }, onCompleted: () => { toast.success({ title: 'Saved' }); }, }); <Button onPress={handleSubmit} isDisabled={!isValid || loading} isLoading={loading} > Submit </Button> ``` ## Query Options ### Fetch Policies | Policy | Use When | |--------|----------| | `cache-first` | Data rarely changes | | `cache-and-network` | Want fast + fresh (default) | | `network-only` | Always need latest | | `no-cache` | Never cache (rare) | ### Common Options ```typescript useGetItemsQuery({ variables: { id: itemId }, // Fetch strategy fetchPolicy: 'cache-and-network', // Re-render on network status changes notifyOnNetworkStatusChange: true, // Skip if condition not met skip: !itemId, // Poll for updates pollInterval: 30000, }); ``` ## Optimistic Updates For instant UI feedback: ```typescript const [toggleFavorite] = useToggleFavoriteMutation({ optimisticResponse: { toggleFavorite: { __typename: 'Item', id: itemId, isFavorite: !currentState, }, }, onError: (error) => { // Rollback happens automatically console.error('toggleFavorite failed:', error); toast.error({ title: 'Failed to update' }); }, }); ``` ### When NOT to Use Optimistic Updates - Operations that can fail validation - Operations with server-generated values - Destructive operations (delete) - Operations affecting other users ## Fragments For reusable field selections: ```graphql # src/graphql/fragments/ItemFields.gql fragment ItemFields on Item { id name description createdAt updatedAt } ``` Use in queries: ```graphql query GetItems { items { ...ItemFields } } ``` ## Anti-Patterns ```typescript // WRONG - Inline gql const GET_ITEMS = gql` query GetItems { items { id } } `; // CORRECT - Use .gql file + generated hook import { useGetItemsQuery } from './GetItems.generated'; // WRONG - No error handler const [mutate] = useMutation(MUTATION); // CORRECT - Always handle errors const [mutate] = useMutation(MUTATION, { onError: (error) => { console.error('mutation failed:', error); toast.error({ title: 'Operation failed' }); }, }); // WRONG - Button not disabled during mutation <Button onPress={submit}>Submit</Button> // CORRECT - Disabled and loading <Button onPress={submit} isDisabled={loading} isLoading={loading}> Submit </Button> ``` ## Codegen Commands ```bash # Generate types from .gql files npm run gql:typegen # Download schema + generate types npm run sync-types ``` ## Integration with Other Skills - **react-ui-patterns**: Loading/error/empty states for queries - **testing-patterns**: Mock generated hooks in tests - **formik-patterns**: Mutation submission patterns
GitHub에서 보기