Skip to main content

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.

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:
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:
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.
type Supplement {
  ingredients: String
  benefits: [String]
  presentation: String
  dosage: String
  warnings: String
  storage: String
}

type ProductExtension {
  supplement: Supplement
}

extend type Product {
  extension: ProductExtension
}

Resolver Context

Resolvers receive three arguments:
root
object
The parent object. For top-level resolvers (Query, Mutation), this is typically undefined.
args
object
The arguments passed to the field in the GraphQL query.
context
object
A shared context object available to all resolvers. Contains request information, database connections, and authentication data.

Field Resolvers

Field resolvers define how individual fields are resolved from their parent object:
export default {
  Foo: {
    id: (foo) => foo.id,
    name: (foo) => foo.name,
    description: (foo) => foo.description
  }
};
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.

Creating Custom Types

To create a new GraphQL type in your extension:
  1. Create a directory for your type:
    mkdir -p extensions/[name]/src/graphql/types/[TypeName]
    
  2. Define your type schema in [TypeName].graphql:
    type CustomType {
      id: ID!
      field: String
    }
    
    type Query {
      customType(id: ID!): CustomType
    }
    
  3. Implement resolvers in [TypeName].resolvers.js:
    export default {
      Query: {
        customType: (root, { id }, context) => {
          // Implementation
        }
      }
    };
    

Data Fetching in Page Components

Page components can fetch GraphQL data using the query export:
// 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

Use Strong Types

Define explicit types for all fields. Use non-null types (!) for required fields.

Avoid N+1 Queries

Consider using DataLoader or batching strategies for related data fetching.

Keep Resolvers Simple

Move complex business logic to separate service functions.

Document Your Schema

Use GraphQL descriptions to document types and fields.

Error Handling

Resolvers should throw errors when operations fail:
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

GraphQL Queries

Explore available queries and learn how to fetch data

GraphQL Mutations

Learn how to create mutations for data modification

Build docs developers (and LLMs) love