# GraphQL Resolver Example

GraphQL API resolvers

## Code Example

```javascript
// GraphQL API Resolvers Example
const { ApolloServer } = require('apollo-server-express');
const { buildSchema } = require('graphql');
const express = require('express');

// Sample data (use database in production)
let users = [
  { id: '1', name: 'John Doe', email: 'john@example.com', age: 30, posts: [] },
  { id: '2', name: 'Jane Smith', email: 'jane@example.com', age: 25, posts: [] }
];

let posts = [
  { id: '1', title: 'First Post', content: 'This is my first post', authorId: '1', published: true },
  { id: '2', title: 'Second Post', content: 'This is my second post', authorId: '1', published: false },
  { id: '3', title: 'Third Post', content: 'This is my third post', authorId: '2', published: true }
];

// GraphQL Schema
const typeDefs = `
  type User {
    id: ID!
    name: String!
    email: String!
    age: Int
    posts: [Post!]!
  }

  type Post {
    id: ID!
    title: String!
    content: String!
    author: User!
    published: Boolean!
    createdAt: String!
  }

  type Query {
    users: [User!]!
    user(id: ID!): User
    posts: [Post!]!
    post(id: ID!): Post
    searchUsers(query: String!): [User!]!
    publishedPosts: [Post!]!
  }

  type Mutation {
    createUser(input: CreateUserInput!): User!
    updateUser(id: ID!, input: UpdateUserInput!): User
    deleteUser(id: ID!): Boolean!
    createPost(input: CreatePostInput!): Post!
    updatePost(id: ID!, input: UpdatePostInput!): Post
    deletePost(id: ID!): Boolean!
  }

  input CreateUserInput {
    name: String!
    email: String!
    age: Int
  }

  input UpdateUserInput {
    name: String
    email: String
    age: Int
  }

  input CreatePostInput {
    title: String!
    content: String!
    authorId: ID!
    published: Boolean = false
  }

  input UpdatePostInput {
    title: String
    content: String
    published: Boolean
  }
`;

// Resolvers
const resolvers = {
  Query: {
    users: () => users,
    
    user: (_, { id }) => {
      const user = users.find(u => u.id === id);
      if (!user) {
        throw new Error(`User with ID ${id} not found`);
      }
      return user;
    },
    
    posts: () => posts,
    
    post: (_, { id }) => {
      const post = posts.find(p => p.id === id);
      if (!post) {
        throw new Error(`Post with ID ${id} not found`);
      }
      return post;
    },
    
    searchUsers: (_, { query }) => {
      return users.filter(user => 
        user.name.toLowerCase().includes(query.toLowerCase()) ||
        user.email.toLowerCase().includes(query.toLowerCase())
      );
    },
    
    publishedPosts: () => posts.filter(post => post.published)
  },

  Mutation: {
    createUser: (_, { input }) => {
      const user = {
        id: (users.length + 1).toString(),
        ...input,
        posts: []
      };
      users.push(user);
      return user;
    },
    
    updateUser: (_, { id, input }) => {
      const userIndex = users.findIndex(u => u.id === id);
      if (userIndex === -1) {
        throw new Error(`User with ID ${id} not found`);
      }
      
      users[userIndex] = { ...users[userIndex], ...input };
      return users[userIndex];
    },
    
    deleteUser: (_, { id }) => {
      const userIndex = users.findIndex(u => u.id === id);
      if (userIndex === -1) {
        throw new Error(`User with ID ${id} not found`);
      }
      
      users.splice(userIndex, 1);
      // Also delete user's posts
      posts = posts.filter(p => p.authorId !== id);
      return true;
    },
    
    createPost: (_, { input }) => {
      const author = users.find(u => u.id === input.authorId);
      if (!author) {
        throw new Error(`User with ID ${input.authorId} not found`);
      }
      
      const post = {
        id: (posts.length + 1).toString(),
        ...input,
        createdAt: new Date().toISOString()
      };
      posts.push(post);
      return post;
    },
    
    updatePost: (_, { id, input }) => {
      const postIndex = posts.findIndex(p => p.id === id);
      if (postIndex === -1) {
        throw new Error(`Post with ID ${id} not found`);
      }
      
      posts[postIndex] = { ...posts[postIndex], ...input };
      return posts[postIndex];
    },
    
    deletePost: (_, { id }) => {
      const postIndex = posts.findIndex(p => p.id === id);
      if (postIndex === -1) {
        throw new Error(`Post with ID ${id} not found`);
      }
      
      posts.splice(postIndex, 1);
      return true;
    }
  },

  User: {
    posts: (user) => posts.filter(post => post.authorId === user.id)
  },

  Post: {
    author: (post) => users.find(user => user.id === post.authorId)
  }
};

// Create Apollo Server
const server = new ApolloServer({
  typeDefs,
  resolvers,
  context: ({ req }) => {
    // Add authentication context here
    return {
      user: req.user || null
    };
  },
  formatError: (error) => {
    console.error('GraphQL Error:', error);
    return {
      message: error.message,
      locations: error.locations,
      path: error.path
    };
  }
});

const app = express();

// Apply middleware
server.applyMiddleware({ app, path: '/graphql' });

const PORT = process.env.PORT || 4000;
app.listen(PORT, () => {
  console.log(`GraphQL server running at http://localhost:${PORT}${server.graphqlPath}`);
});

module.exports = { server, app };
```

## Files

- server.js
- schema.js
- resolvers.js
- types.js

## Usage

```bash
# Install dependencies
npm install

# Run the example
npm start
```
