> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/Antony-Figueroa/my-evershop-app/llms.txt
> Use this file to discover all available pages before exploring further.

# GraphQL API Overview

> Learn about the GraphQL API architecture in EverShop and how to extend it

## Introduction

EverShop provides a powerful GraphQL API that allows you to query and manipulate data in your e-commerce application. The GraphQL implementation follows a modular architecture where each extension can define its own types, queries, and mutations.

## Architecture

### Modular Type System

GraphQL types and resolvers in EverShop are organized within extensions, following this structure:

```
extensions/[name]/src/graphql/types/[Type]/
├── [Type].graphql      # Type definitions
└── [Type].resolvers.js # Resolver implementations
```

### Type Definition Files

Type definitions use the GraphQL Schema Definition Language (SDL) and are stored in `.graphql` files:

```graphql theme={null}
type Foo {
  id: ID!
  name: String!
  description: String
}

type Query {
  foo(id: ID!): Foo
  foos: [Foo!]!
}
```

### Resolver Files

Resolvers are JavaScript/TypeScript files that implement the logic for fetching and transforming data:

```javascript theme={null}
export default {
  Query: {
    foo: (root, { id }, context) => {
      // Query logic here
      return { id, name: 'Sample' };
    },
    foos: (root, args, context) => {
      // Return array of items
      return [];
    }
  },
  Foo: {
    id: (foo) => foo.id,
    name: (foo) => foo.name,
    description: (foo) => foo.description
  }
};
```

## Type Extension Pattern

EverShop supports extending existing GraphQL types using the `extend type` directive. This is particularly useful for adding custom fields to core types like `Product`.

<CodeGroup>
  ```graphql extensions/productCatalog/src/graphql/types/ProductExtension/ProductExtension.graphql theme={null}
  type Supplement {
    ingredients: String
    benefits: [String]
    presentation: String
    dosage: String
    warnings: String
    storage: String
  }

  type ProductExtension {
    supplement: Supplement
  }

  extend type Product {
    extension: ProductExtension
  }
  ```

  ```javascript ProductExtension.resolvers.js theme={null}
  export default {
    Product: {
      extension: (product) => {
        return {
          supplement: {
            ingredients: product.ingredients || null,
            benefits: product.benefits ? JSON.parse(product.benefits) : null,
            presentation: product.presentation || null,
            dosage: product.dosage || null,
            warnings: product.warnings || null,
            storage: product.storage || null
          }
        };
      }
    }
  };
  ```
</CodeGroup>

## Resolver Context

Resolvers receive three arguments:

<ParamField path="root" type="object">
  The parent object. For top-level resolvers (Query, Mutation), this is typically undefined.
</ParamField>

<ParamField path="args" type="object">
  The arguments passed to the field in the GraphQL query.
</ParamField>

<ParamField path="context" type="object">
  A shared context object available to all resolvers. Contains request information, database connections, and authentication data.
</ParamField>

## Field Resolvers

Field resolvers define how individual fields are resolved from their parent object:

```javascript theme={null}
export default {
  Foo: {
    id: (foo) => foo.id,
    name: (foo) => foo.name,
    description: (foo) => foo.description
  }
};
```

<Note>
  Field resolvers are optional. If not defined, GraphQL will use the default resolver which returns the property with the same name from the parent object.
</Note>

## Creating Custom Types

To create a new GraphQL type in your extension:

1. Create a directory for your type:
   ```bash theme={null}
   mkdir -p extensions/[name]/src/graphql/types/[TypeName]
   ```

2. Define your type schema in `[TypeName].graphql`:
   ```graphql theme={null}
   type CustomType {
     id: ID!
     field: String
   }

   type Query {
     customType(id: ID!): CustomType
   }
   ```

3. Implement resolvers in `[TypeName].resolvers.js`:
   ```javascript theme={null}
   export default {
     Query: {
       customType: (root, { id }, context) => {
         // Implementation
       }
     }
   };
   ```

## Data Fetching in Page Components

Page components can fetch GraphQL data using the `query` export:

```typescript theme={null}
// Component
export default function MyComponent({ data }) {
  return (
    <div>
      {data.foos.map(foo => (
        <div key={foo.id}>{foo.name}</div>
      ))}
    </div>
  );
}

// Layout
export const layout = {
  areaId: 'content',
  sortOrder: 10
};

// GraphQL Query
export const query = `
  query {
    foos {
      id
      name
      description
    }
  }
`;
```

## Best Practices

<CardGroup cols={2}>
  <Card title="Use Strong Types" icon="shield-check">
    Define explicit types for all fields. Use non-null types (`!`) for required fields.
  </Card>

  <Card title="Avoid N+1 Queries" icon="database">
    Consider using DataLoader or batching strategies for related data fetching.
  </Card>

  <Card title="Keep Resolvers Simple" icon="code">
    Move complex business logic to separate service functions.
  </Card>

  <Card title="Document Your Schema" icon="file-lines">
    Use GraphQL descriptions to document types and fields.
  </Card>
</CardGroup>

## Error Handling

Resolvers should throw errors when operations fail:

```javascript theme={null}
export default {
  Query: {
    foo: (root, { id }, context) => {
      const item = findFoo(id);
      if (!item) {
        throw new Error(`Foo with id ${id} not found`);
      }
      return item;
    }
  }
};
```

## Next Steps

<CardGroup cols={2}>
  <Card title="GraphQL Queries" icon="magnifying-glass" href="/api/graphql/queries">
    Explore available queries and learn how to fetch data
  </Card>

  <Card title="GraphQL Mutations" icon="pen-to-square" href="/api/graphql/mutations">
    Learn how to create mutations for data modification
  </Card>
</CardGroup>
