nitro-graphql 2.0.0-beta.4 → 2.0.0-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,17 +1,20 @@
1
- # Nitro GraphQL
2
-
3
1
  <div align="center">
4
2
 
3
+ <img src="./.docs/public/logo.svg" alt="Nitro GraphQL Logo" width="120" height="120">
4
+
5
+ # Nitro GraphQL
6
+
5
7
  [![npm version][npm-version-src]][npm-version-href]
6
8
  [![npm downloads][npm-downloads-src]][npm-downloads-href]
7
9
  [![bundle][bundle-src]][bundle-href]
8
10
  [![License][license-src]][license-href]
11
+ [![Documentation][docs-src]][docs-href]
9
12
 
10
13
  **The easiest way to add GraphQL to any Nitro application**
11
14
 
12
15
  🚀 **Auto-discovery** • 📝 **Type Generation** • 🎮 **Apollo Sandbox** • 🔧 **Zero Config**
13
16
 
14
- [Quick Start](#-quick-start) • [Examples](#-examples) • [Documentation](#-documentation) • [Community](#-community)
17
+ [📚 Documentation](https://nitro-graphql.pages.dev) • [Quick Start](#-quick-start) • [Examples](#-examples) • [Community](#-community)
15
18
 
16
19
  </div>
17
20
 
@@ -238,6 +241,246 @@ query {
238
241
 
239
242
  ## 🚀 Advanced Features
240
243
 
244
+ <details>
245
+ <summary><strong>🎛️ Custom File Generation & Paths</strong></summary>
246
+
247
+ Control which files are auto-generated and customize their output paths. Perfect for library development, monorepos, or custom project structures.
248
+
249
+ ### Library Mode
250
+
251
+ Disable all scaffold files for library/module development:
252
+
253
+ ```ts
254
+ // nitro.config.ts
255
+ export default defineNitroConfig({
256
+ graphql: {
257
+ framework: 'graphql-yoga',
258
+ scaffold: false, // Disable all scaffold files
259
+ clientUtils: false, // Disable client utilities
260
+ }
261
+ })
262
+ ```
263
+
264
+ ### Fine-Grained Control
265
+
266
+ Control each file individually:
267
+
268
+ ```ts
269
+ export default defineNitroConfig({
270
+ graphql: {
271
+ framework: 'graphql-yoga',
272
+
273
+ // Scaffold files
274
+ scaffold: {
275
+ graphqlConfig: false, // Don't generate graphql.config.ts
276
+ serverSchema: true, // Generate server/graphql/schema.ts
277
+ serverConfig: true, // Generate server/graphql/config.ts
278
+ serverContext: false, // Don't generate server/graphql/context.ts
279
+ },
280
+
281
+ // Client utilities (Nuxt only)
282
+ clientUtils: {
283
+ index: true, // Generate app/graphql/index.ts
284
+ ofetch: false, // Don't generate ofetch wrappers
285
+ },
286
+
287
+ // SDK files
288
+ sdk: {
289
+ main: true, // Generate default SDK
290
+ external: true, // Generate external service SDKs
291
+ },
292
+
293
+ // Type files
294
+ types: {
295
+ server: true, // Generate server types
296
+ client: true, // Generate client types
297
+ external: true, // Generate external service types
298
+ }
299
+ }
300
+ })
301
+ ```
302
+
303
+ ### Custom Paths
304
+
305
+ Customize where files are generated:
306
+
307
+ ```ts
308
+ export default defineNitroConfig({
309
+ graphql: {
310
+ framework: 'graphql-yoga',
311
+
312
+ // Method 1: Global paths (affects all files)
313
+ paths: {
314
+ serverGraphql: 'src/server/graphql',
315
+ clientGraphql: 'src/client/graphql',
316
+ buildDir: '.build',
317
+ typesDir: '.build/types',
318
+ },
319
+
320
+ // Method 2: Specific file paths
321
+ scaffold: {
322
+ serverSchema: 'lib/graphql/schema.ts',
323
+ serverConfig: 'lib/graphql/config.ts',
324
+ },
325
+
326
+ sdk: {
327
+ main: 'app/graphql/organization/sdk.ts',
328
+ external: 'app/graphql/{serviceName}/client-sdk.ts',
329
+ },
330
+
331
+ types: {
332
+ server: 'types/graphql-server.d.ts',
333
+ client: 'types/graphql-client.d.ts',
334
+ }
335
+ }
336
+ })
337
+ ```
338
+
339
+ ### Path Placeholders
340
+
341
+ Use placeholders in custom paths:
342
+
343
+ | Placeholder | Description | Example |
344
+ |------------|-------------|---------|
345
+ | `{serviceName}` | External service name | `github`, `stripe` |
346
+ | `{buildDir}` | Build directory | `.nitro` or `.nuxt` |
347
+ | `{rootDir}` | Root directory | `/Users/you/project` |
348
+ | `{framework}` | Framework name | `nuxt` or `nitro` |
349
+ | `{typesDir}` | Types directory | `.nitro/types` |
350
+ | `{serverGraphql}` | Server GraphQL dir | `server/graphql` |
351
+ | `{clientGraphql}` | Client GraphQL dir | `app/graphql` |
352
+
353
+ Example:
354
+ ```ts
355
+ sdk: {
356
+ external: '{clientGraphql}/{serviceName}/sdk.ts'
357
+ }
358
+ // → app/graphql/github/sdk.ts
359
+ // → app/graphql/stripe/sdk.ts
360
+ ```
361
+
362
+ ### Service-Specific Paths
363
+
364
+ Customize paths for individual external services:
365
+
366
+ ```ts
367
+ export default defineNuxtConfig({
368
+ nitro: {
369
+ graphql: {
370
+ framework: 'graphql-yoga',
371
+
372
+ // Global default for all external services
373
+ sdk: {
374
+ external: 'app/graphql/{serviceName}/sdk.ts'
375
+ },
376
+
377
+ externalServices: [
378
+ {
379
+ name: 'github',
380
+ endpoint: 'https://api.github.com/graphql',
381
+ schema: 'https://api.github.com/graphql',
382
+
383
+ // GitHub-specific paths (override global config)
384
+ paths: {
385
+ sdk: 'app/graphql/organization/github-sdk.ts',
386
+ types: 'types/github.d.ts',
387
+ ofetch: 'app/graphql/organization/github-client.ts'
388
+ }
389
+ },
390
+ {
391
+ name: 'stripe',
392
+ endpoint: 'https://api.stripe.com/graphql',
393
+ schema: 'https://api.stripe.com/graphql',
394
+
395
+ // Stripe-specific paths
396
+ paths: {
397
+ sdk: 'app/graphql/payments/stripe-sdk.ts',
398
+ types: 'types/payments/stripe.d.ts',
399
+ // ofetch uses global config
400
+ }
401
+ },
402
+ {
403
+ name: 'shopify',
404
+ endpoint: 'https://api.shopify.com/graphql',
405
+ // No paths → uses global config
406
+ // → app/graphql/shopify/sdk.ts
407
+ }
408
+ ]
409
+ }
410
+ }
411
+ })
412
+ ```
413
+
414
+ ### Path Resolution Priority
415
+
416
+ When resolving file paths, the system follows this priority order:
417
+
418
+ 1. **Service-specific path** (for external services): `service.paths.sdk`
419
+ 2. **Category config**: `sdk.external` or `sdk.main`
420
+ 3. **Global paths**: `paths.clientGraphql`
421
+ 4. **Framework defaults**: Nuxt vs Nitro defaults
422
+
423
+ Example:
424
+ ```ts
425
+ // Given this config:
426
+ {
427
+ paths: { clientGraphql: 'custom/graphql' },
428
+ sdk: { external: '{clientGraphql}/{serviceName}/sdk.ts' },
429
+ externalServices: [
430
+ {
431
+ name: 'github',
432
+ paths: { sdk: 'app/org/github-sdk.ts' } // ← Wins (priority 1)
433
+ },
434
+ {
435
+ name: 'stripe',
436
+ // Uses sdk.external (priority 2)
437
+ // → custom/graphql/stripe/sdk.ts
438
+ }
439
+ ]
440
+ }
441
+ ```
442
+
443
+ ### Use Cases
444
+
445
+ **Monorepo structure:**
446
+ ```ts
447
+ paths: {
448
+ serverGraphql: 'packages/api/src/graphql',
449
+ clientGraphql: 'packages/web/src/graphql',
450
+ typesDir: 'packages/types/src/generated',
451
+ }
452
+ ```
453
+
454
+ **Multiple external service organizations:**
455
+ ```ts
456
+ externalServices: [
457
+ {
458
+ name: 'github',
459
+ paths: { sdk: 'app/graphql/vcs/github-sdk.ts' }
460
+ },
461
+ {
462
+ name: 'gitlab',
463
+ paths: { sdk: 'app/graphql/vcs/gitlab-sdk.ts' }
464
+ },
465
+ {
466
+ name: 'stripe',
467
+ paths: { sdk: 'app/graphql/billing/stripe-sdk.ts' }
468
+ }
469
+ ]
470
+ ```
471
+
472
+ **Library development (no scaffolding):**
473
+ ```ts
474
+ {
475
+ scaffold: false,
476
+ clientUtils: false,
477
+ sdk: { enabled: true }, // Only generate SDKs
478
+ types: { enabled: true }, // Only generate types
479
+ }
480
+ ```
481
+
482
+ </details>
483
+
241
484
  <details>
242
485
  <summary><strong>🎭 Custom Directives</strong></summary>
243
486
 
@@ -400,6 +643,79 @@ server/
400
643
  })
401
644
  ```
402
645
 
646
+ **RollupError: "[exportName]" is not exported by "[file].resolver.ts"**
647
+
648
+ This error occurs when the resolver scanner can't find the expected export in your resolver file. Common causes:
649
+
650
+ 1. **Using default export instead of named export** ❌
651
+ ```ts
652
+ // ❌ WRONG - Will not be detected
653
+ export default defineQuery({
654
+ users: () => [...]
655
+ })
656
+ ```
657
+
658
+ ```ts
659
+ // ✅ CORRECT - Use named export
660
+ export const userQueries = defineQuery({
661
+ users: () => [...]
662
+ })
663
+ ```
664
+
665
+ 2. **Not using a define function** ❌
666
+ ```ts
667
+ // ❌ WRONG - Plain object won't be detected
668
+ export const resolvers = {
669
+ Query: {
670
+ users: () => [...]
671
+ }
672
+ }
673
+ ```
674
+
675
+ ```ts
676
+ // ✅ CORRECT - Use defineResolver, defineQuery, etc.
677
+ export const userResolver = defineResolver({
678
+ Query: {
679
+ users: () => [...]
680
+ }
681
+ })
682
+ ```
683
+
684
+ 3. **File naming doesn't match export** ❌
685
+ ```ts
686
+ // ❌ File: uploadFile.resolver.ts but export is named differently
687
+ export const fileUploader = defineMutation({...})
688
+ ```
689
+
690
+ ```ts
691
+ // ✅ CORRECT - Export name can be anything, as long as it uses a define function
692
+ export const uploadFile = defineMutation({...})
693
+ export const fileUploader = defineMutation({...}) // Both work!
694
+ ```
695
+
696
+ 4. **Syntax errors preventing parsing**
697
+ - Check for TypeScript compilation errors in the file
698
+ - Ensure imports are valid
699
+ - Verify no missing brackets or syntax issues
700
+
701
+ **How resolver scanning works:**
702
+ - The module uses `oxc-parser` to scan `.resolver.ts` files
703
+ - It looks for **named exports** using these functions:
704
+ - `defineResolver` - Complete resolver with Query, Mutation, etc.
705
+ - `defineQuery` - Query-only resolvers
706
+ - `defineMutation` - Mutation-only resolvers
707
+ - `defineType` - Custom type resolvers
708
+ - `defineSubscription` - Subscription resolvers
709
+ - `defineDirective` - Directive resolvers
710
+ - Only exports using these functions are included in the virtual module
711
+
712
+ **Debugging steps:**
713
+ 1. Check your resolver file uses named exports: `export const name = defineQuery({...})`
714
+ 2. Verify you're using one of the define functions listed above
715
+ 3. Look for TypeScript/syntax errors in the file
716
+ 4. Restart the dev server after fixing
717
+ 5. If issues persist, simplify the resolver to test (single query)
718
+
403
719
  </details>
404
720
 
405
721
  ## 🌟 Production Usage
@@ -408,6 +724,469 @@ This package powers production applications:
408
724
 
409
725
  - [**Nitroping**](https://github.com/productdevbook/nitroping) - Self-hosted push notification service
410
726
 
727
+ ## 🤖 Using Claude Code
728
+
729
+ Speed up development with [Claude Code](https://claude.ai/code) — AI-powered assistance for setting up and building with nitro-graphql.
730
+
731
+ ### Quick Setup Prompts
732
+
733
+ Copy and paste these prompts into Claude Code to scaffold a complete GraphQL API.
734
+
735
+ **💡 Tip**: After pasting, Claude Code will execute step-by-step and validate each action.
736
+
737
+ <details>
738
+ <summary>🟢 <strong>Nuxt Project</strong></summary>
739
+
740
+ ```
741
+ ## GOAL
742
+ Set up nitro-graphql in this Nuxt project with a User management GraphQL API.
743
+
744
+ ## PREREQUISITES
745
+ Check if this is a Nuxt project by looking for nuxt.config.ts in the root.
746
+
747
+ ## STEP 1: INSTALL DEPENDENCIES
748
+ Action: Run this command
749
+ Command: pnpm add nitro-graphql graphql-yoga graphql
750
+ Validation: Check package.json contains these packages
751
+
752
+ ## STEP 2: CONFIGURE NUXT
753
+ File: nuxt.config.ts
754
+ Action: EDIT (add to existing config, don't replace)
755
+ Add these properties:
756
+
757
+ export default defineNuxtConfig({
758
+ modules: ['nitro-graphql/nuxt'], // Add this module
759
+ nitro: {
760
+ graphql: {
761
+ framework: 'graphql-yoga',
762
+ },
763
+ },
764
+ })
765
+
766
+ Validation: Check the file has modules array and nitro.graphql config
767
+
768
+ ## STEP 3: CREATE SCHEMA
769
+ File: server/graphql/schema.graphql
770
+ Action: CREATE NEW FILE (create server/graphql/ directory if needed)
771
+ Content:
772
+
773
+ type User {
774
+ id: ID!
775
+ name: String!
776
+ email: String!
777
+ }
778
+
779
+ type Query {
780
+ users: [User!]!
781
+ user(id: ID!): User
782
+ }
783
+
784
+ type Mutation {
785
+ _empty: String
786
+ }
787
+
788
+ Validation: File should be in server/graphql/ directory
789
+
790
+ ## STEP 4: CREATE CONTEXT (Optional but recommended)
791
+ File: server/graphql/context.ts
792
+ Action: CREATE NEW FILE (auto-generated on first run, but create manually for clarity)
793
+ Content:
794
+
795
+ // Extend H3 event context with custom properties
796
+ declare module 'h3' {
797
+ interface H3EventContext {
798
+ // Add your custom context properties here
799
+ // Example:
800
+ // db?: Database
801
+ // auth?: { userId: string }
802
+ }
803
+ }
804
+
805
+ Note: This file lets you add custom properties to resolver context
806
+ Validation: File exists in server/graphql/
807
+
808
+ ## STEP 5: CREATE CONFIG (Optional)
809
+ File: server/graphql/config.ts
810
+ Action: CREATE NEW FILE (auto-generated, customize if needed)
811
+ Content:
812
+
813
+ // Custom GraphQL Yoga configuration
814
+ export default defineGraphQLConfig({
815
+ // Custom context enhancer, plugins, etc.
816
+ // See: https://the-guild.dev/graphql/yoga-server/docs
817
+ })
818
+
819
+ Note: Use this to customize GraphQL Yoga options
820
+ Validation: File exists in server/graphql/
821
+
822
+ ## STEP 6: CREATE RESOLVERS
823
+ File: server/graphql/users.resolver.ts
824
+ Action: CREATE NEW FILE
825
+ Content:
826
+
827
+ // ⚠️ CRITICAL: Use NAMED EXPORTS (not default export)
828
+ export const userQueries = defineQuery({
829
+ users: async (_, __, context) => {
830
+ // context is H3EventContext - access event, storage, etc.
831
+ return [
832
+ { id: '1', name: 'John Doe', email: 'john@example.com' },
833
+ { id: '2', name: 'Jane Smith', email: 'jane@example.com' }
834
+ ]
835
+ },
836
+ user: async (_, { id }, context) => {
837
+ // Third parameter is context (H3EventContext)
838
+ const users = [
839
+ { id: '1', name: 'John Doe', email: 'john@example.com' },
840
+ { id: '2', name: 'Jane Smith', email: 'jane@example.com' }
841
+ ]
842
+ return users.find(u => u.id === id) || null
843
+ }
844
+ })
845
+
846
+ Validation: File ends with .resolver.ts and uses named export
847
+
848
+ ## STEP 7: START DEV SERVER
849
+ Command: pnpm dev
850
+ Expected Output: Server starts on http://localhost:3000
851
+ Wait for: "Nitro built in X ms" message
852
+ Note: context.ts and config.ts will auto-generate if you skipped steps 4-5
853
+
854
+ ## VALIDATION CHECKLIST
855
+ - [ ] Navigate to http://localhost:3000/api/graphql - should show GraphQL playground
856
+ - [ ] Health check: http://localhost:3000/api/graphql/health - should return OK
857
+ - [ ] Run this query in playground:
858
+ ```graphql
859
+ query {
860
+ users {
861
+ id
862
+ name
863
+ email
864
+ }
865
+ }
866
+ ```
867
+ Expected: Returns 2 users
868
+ - [ ] Check .nuxt/types/nitro-graphql-server.d.ts exists (types auto-generated)
869
+
870
+ ## FILE STRUCTURE CREATED
871
+ ```
872
+ server/
873
+ graphql/
874
+ schema.graphql ← GraphQL type definitions
875
+ context.ts ← H3 event context augmentation (optional)
876
+ config.ts ← GraphQL Yoga config (optional)
877
+ users.resolver.ts ← Query resolvers
878
+ .nuxt/
879
+ types/
880
+ nitro-graphql-server.d.ts ← Auto-generated types
881
+ graphql.config.ts ← Auto-generated (for IDE tooling)
882
+ ```
883
+
884
+ ## CRITICAL RULES (MUST FOLLOW)
885
+ ❌ DO NOT use default exports in resolvers
886
+ Wrong: export default defineQuery({...})
887
+ Right: export const userQueries = defineQuery({...})
888
+
889
+ ❌ DO NOT name files without .resolver.ts extension
890
+ Wrong: users.ts or user-resolver.ts
891
+ Right: users.resolver.ts or user.resolver.ts
892
+
893
+ ✅ DO use named exports for all resolvers
894
+ ✅ DO place files in server/graphql/ directory
895
+ ✅ DO restart dev server if types don't generate
896
+
897
+ ## TROUBLESHOOTING
898
+ Issue: "GraphQL endpoint returns 404"
899
+ Fix: Ensure 'nitro-graphql/nuxt' is in modules array (not just 'nitro-graphql')
900
+
901
+ Issue: "defineQuery is not defined"
902
+ Fix: Restart dev server - auto-imports need to regenerate
903
+
904
+ Issue: "Types not generating"
905
+ Fix: Check .nuxt/types/nitro-graphql-server.d.ts exists, if not restart dev server
906
+
907
+ Issue: "Module not found: nitro-graphql"
908
+ Fix: Run pnpm install again, check package.json has the package
909
+
910
+ ## NEXT STEPS (After Setup Works)
911
+ 1. Add mutations: "Add createUser and deleteUser mutations with H3 storage"
912
+ 2. Extend context: "Add database connection to context.ts and use it in resolvers"
913
+ 3. Use types: "Import and use TypeScript types from #graphql/server in resolvers"
914
+ 4. Add auth: "Add authentication middleware using context in resolvers"
915
+ 5. Custom config: "Configure GraphQL Yoga plugins in config.ts"
916
+
917
+ Now implement this setup step-by-step.
918
+ ```
919
+
920
+ </details>
921
+
922
+ <details>
923
+ <summary>⚡ <strong>Nitro Project</strong></summary>
924
+
925
+ ```
926
+ Set up nitro-graphql in this Nitro project following these exact specifications:
927
+
928
+ INSTALLATION:
929
+ 1. Run: pnpm add nitro-graphql graphql-yoga graphql
930
+
931
+ CONFIGURATION (nitro.config.ts):
932
+ import { defineNitroConfig } from 'nitro/config'
933
+
934
+ export default defineNitroConfig({
935
+ modules: ['nitro-graphql'],
936
+ graphql: {
937
+ framework: 'graphql-yoga',
938
+ },
939
+ })
940
+
941
+ SCHEMA (server/graphql/schema.graphql):
942
+ type Product {
943
+ id: ID!
944
+ name: String!
945
+ price: Float!
946
+ }
947
+
948
+ input CreateProductInput {
949
+ name: String!
950
+ price: Float!
951
+ }
952
+
953
+ type Query {
954
+ products: [Product!]!
955
+ product(id: ID!): Product
956
+ }
957
+
958
+ type Mutation {
959
+ createProduct(input: CreateProductInput!): Product!
960
+ }
961
+
962
+ RESOLVERS (server/graphql/products.resolver.ts):
963
+ // Use NAMED EXPORTS only
964
+ export const productQueries = defineQuery({
965
+ products: async (_, __, context) => {
966
+ // Access H3 event context
967
+ const products = await context.storage?.getItem('products') || []
968
+ return products
969
+ },
970
+ product: async (_, { id }, context) => {
971
+ const products = await context.storage?.getItem('products') || []
972
+ return products.find(p => p.id === id)
973
+ }
974
+ })
975
+
976
+ export const productMutations = defineMutation({
977
+ createProduct: async (_, { input }, context) => {
978
+ const products = await context.storage?.getItem('products') || []
979
+ const product = {
980
+ id: Date.now().toString(),
981
+ ...input
982
+ }
983
+ products.push(product)
984
+ await context.storage?.setItem('products', products)
985
+ return product
986
+ }
987
+ })
988
+
989
+ KEY RULES:
990
+ - Files: *.graphql for schemas, *.resolver.ts for resolvers
991
+ - MUST use named exports (not default export)
992
+ - defineQuery and defineMutation are auto-imported
993
+ - Context is the third parameter (access H3 event context)
994
+ - Endpoint: http://localhost:3000/api/graphql
995
+
996
+ Now implement this setup.
997
+ ```
998
+
999
+ </details>
1000
+
1001
+ <details>
1002
+ <summary>🎮 <strong>Apollo Server Setup</strong></summary>
1003
+
1004
+ ```
1005
+ Set up nitro-graphql with Apollo Server following these exact specifications:
1006
+
1007
+ INSTALLATION:
1008
+ 1. Run: pnpm add nitro-graphql @apollo/server @apollo/utils.withrequired @as-integrations/h3 graphql
1009
+
1010
+ CONFIGURATION (nitro.config.ts):
1011
+ import { defineNitroConfig } from 'nitro/config'
1012
+
1013
+ export default defineNitroConfig({
1014
+ modules: ['nitro-graphql'],
1015
+ graphql: {
1016
+ framework: 'apollo-server',
1017
+ },
1018
+ })
1019
+
1020
+ SCHEMA (server/graphql/schema.graphql):
1021
+ type Book {
1022
+ id: ID!
1023
+ title: String!
1024
+ author: String!
1025
+ }
1026
+
1027
+ type Query {
1028
+ books: [Book!]!
1029
+ book(id: ID!): Book
1030
+ }
1031
+
1032
+ type Mutation {
1033
+ addBook(title: String!, author: String!): Book!
1034
+ }
1035
+
1036
+ RESOLVERS (server/graphql/books.resolver.ts):
1037
+ // IMPORTANT: Use NAMED EXPORTS
1038
+ export const bookResolver = defineResolver({
1039
+ Query: {
1040
+ books: async () => {
1041
+ return [
1042
+ { id: '1', title: '1984', author: 'George Orwell' }
1043
+ ]
1044
+ },
1045
+ book: async (_, { id }) => {
1046
+ return { id, title: '1984', author: 'George Orwell' }
1047
+ }
1048
+ },
1049
+ Mutation: {
1050
+ addBook: async (_, { title, author }) => {
1051
+ return {
1052
+ id: Date.now().toString(),
1053
+ title,
1054
+ author
1055
+ }
1056
+ }
1057
+ }
1058
+ })
1059
+
1060
+ KEY RULES:
1061
+ - framework: 'apollo-server' in config
1062
+ - defineResolver for complete resolver maps
1063
+ - Named exports required (export const name = ...)
1064
+ - Apollo Sandbox: http://localhost:3000/api/graphql
1065
+ - Supports Apollo Federation with federation: { enabled: true }
1066
+
1067
+ Now implement this setup.
1068
+ ```
1069
+
1070
+ </details>
1071
+
1072
+ <details>
1073
+ <summary>🔄 <strong>Add Feature to Existing Setup</strong></summary>
1074
+
1075
+ ```
1076
+ Add a complete blog posts feature to my nitro-graphql API following these specifications:
1077
+
1078
+ SCHEMA (server/graphql/posts/post.graphql):
1079
+ type Post {
1080
+ id: ID!
1081
+ title: String!
1082
+ content: String!
1083
+ authorId: ID!
1084
+ createdAt: String!
1085
+ }
1086
+
1087
+ input CreatePostInput {
1088
+ title: String!
1089
+ content: String!
1090
+ authorId: ID!
1091
+ }
1092
+
1093
+ input UpdatePostInput {
1094
+ title: String
1095
+ content: String
1096
+ }
1097
+
1098
+ extend type Query {
1099
+ posts(limit: Int = 10, offset: Int = 0): [Post!]!
1100
+ post(id: ID!): Post
1101
+ }
1102
+
1103
+ extend type Mutation {
1104
+ createPost(input: CreatePostInput!): Post!
1105
+ updatePost(id: ID!, input: UpdatePostInput!): Post
1106
+ deletePost(id: ID!): Boolean!
1107
+ }
1108
+
1109
+ RESOLVERS (server/graphql/posts/post.resolver.ts):
1110
+ // Use NAMED EXPORTS
1111
+ export const postQueries = defineQuery({
1112
+ posts: async (_, { limit, offset }, context) => {
1113
+ const posts = await context.storage?.getItem('posts') || []
1114
+ return posts.slice(offset, offset + limit)
1115
+ },
1116
+ post: async (_, { id }, context) => {
1117
+ const posts = await context.storage?.getItem('posts') || []
1118
+ return posts.find(p => p.id === id) || null
1119
+ }
1120
+ })
1121
+
1122
+ export const postMutations = defineMutation({
1123
+ createPost: async (_, { input }, context) => {
1124
+ const posts = await context.storage?.getItem('posts') || []
1125
+ const post = {
1126
+ id: Date.now().toString(),
1127
+ ...input,
1128
+ createdAt: new Date().toISOString()
1129
+ }
1130
+ posts.push(post)
1131
+ await context.storage?.setItem('posts', posts)
1132
+ return post
1133
+ },
1134
+ updatePost: async (_, { id, input }, context) => {
1135
+ const posts = await context.storage?.getItem('posts') || []
1136
+ const index = posts.findIndex(p => p.id === id)
1137
+ if (index === -1) return null
1138
+ posts[index] = { ...posts[index], ...input }
1139
+ await context.storage?.setItem('posts', posts)
1140
+ return posts[index]
1141
+ },
1142
+ deletePost: async (_, { id }, context) => {
1143
+ const posts = await context.storage?.getItem('posts') || []
1144
+ const filtered = posts.filter(p => p.id !== id)
1145
+ await context.storage?.setItem('posts', filtered)
1146
+ return filtered.length < posts.length
1147
+ }
1148
+ })
1149
+
1150
+ TYPE USAGE:
1151
+ After dev server restarts, types are auto-generated in:
1152
+ - .nitro/types/nitro-graphql-server.d.ts (server types)
1153
+ - .nuxt/types/nitro-graphql-server.d.ts (for Nuxt)
1154
+
1155
+ Import types:
1156
+ import type { Post, CreatePostInput } from '#graphql/server'
1157
+
1158
+ KEY RULES:
1159
+ - Use "extend type" to add to existing Query/Mutation
1160
+ - Named exports required
1161
+ - Context has H3 event properties
1162
+ - Types auto-generate on file changes
1163
+
1164
+ Now implement this feature.
1165
+ ```
1166
+
1167
+ </details>
1168
+
1169
+ ### Working with Your GraphQL API
1170
+
1171
+ Once set up, you can ask Claude Code for help with:
1172
+
1173
+ ```
1174
+ "Add authentication to my GraphQL resolvers"
1175
+ "Create a custom @auth directive for field-level permissions"
1176
+ "Set up type generation for client-side queries"
1177
+ "Add pagination to my users query"
1178
+ "Connect to an external GitHub GraphQL API"
1179
+ "Debug: my types aren't generating in .nitro/types/"
1180
+ "Optimize resolver performance using DataLoader"
1181
+ ```
1182
+
1183
+ ### Tips for Better Results
1184
+
1185
+ - **Start specific**: Include your framework (Nuxt/Nitro), version, and goal
1186
+ - **Reference docs**: Mention "following nitro-graphql conventions" to align with best practices
1187
+ - **Show errors**: Paste error messages for faster debugging
1188
+ - **Test iteratively**: Run `pnpm dev` after each change to verify
1189
+
411
1190
  ## 🛠️ Development
412
1191
 
413
1192
  ```bash
@@ -467,4 +1246,6 @@ pnpm lint
467
1246
  [bundle-src]: https://deno.bundlejs.com/badge?q=nitro-graphql@0.0.4
468
1247
  [bundle-href]: https://deno.bundlejs.com/badge?q=nitro-graphql@0.0.4
469
1248
  [license-src]: https://img.shields.io/github/license/productdevbook/nitro-graphql.svg?style=flat&colorA=080f12&colorB=1fa669
470
- [license-href]: https://github.com/productdevbook/nitro-graphql/blob/main/LICENSE
1249
+ [license-href]: https://github.com/productdevbook/nitro-graphql/blob/main/LICENSE
1250
+ [docs-src]: https://img.shields.io/badge/docs-read-blue?style=flat&colorA=080f12&colorB=1fa669
1251
+ [docs-href]: https://nitro-graphql.pages.dev