GraphQL
GraphQL is a query language and runtime for APIs that lets clients request exactly the data they need. It eliminates over-fetching and under-fetching and provides a strongly typed schema.
1Schema & Queries
# Schema definition
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
createdAt: String!
}type Post { id: ID! title: String! body: String! author: User! tags: [String!]! }
type Query { user(id: ID!): User users(limit: Int, offset: Int): [User!]! posts(authorId: ID, tag: String): [Post!]! }
type Mutation { createUser(name: String!, email: String!): User! updateUser(id: ID!, name: String, email: String): User deleteUser(id: ID!): Boolean! }
type Subscription { postCreated(authorId: ID!): Post! }
# Query from the client query GetUserWithPosts($userId: ID!) { user(id: $userId) { name email posts { id title tags } } } ```
2Resolvers with Apollo Server
import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';const resolvers = { Query: { user: async (_, { id }, { db }) => db.user.findUnique({ where: { id } }), users: async (_, { limit = 20, offset = 0 }, { db }) => db.user.findMany({ take: limit, skip: offset }), posts: async (_, { authorId, tag }, { db }) => db.post.findMany({ where: { ...(authorId && { authorId }), ...(tag && { tags: { has: tag } }), }, }), }, Mutation: { createUser: async (_, args, { db, user }) => { if (!user) throw new Error('Unauthenticated'); return db.user.create({ data: args }); }, }, User: { // Field resolver N+1 solved with DataLoader posts: async (parent, _, { loaders }) => loaders.postsByUserId.load(parent.id), }, };
const server = new ApolloServer({ typeDefs, resolvers }); const { url } = await startStandaloneServer(server, { context: async ({ req }) => ({ db: prisma, user: await authenticate(req.headers.authorization), loaders: createLoaders(prisma), }), }); ```
3GraphQL Best Practices & DataLoader
// ── N+1 Problem & DataLoader ─────────────────────────
import DataLoader from 'dataloader';// Without DataLoader: 100 posts = 100 separate user queries // With DataLoader: 100 posts = 1 batched user query
function createLoaders(db) { return { userById: new DataLoader(async (ids) => { // Batch: fetch all users in one query const users = await db.user.findMany({ where: { id: { in: ids } } }); const userMap = new Map(users.map(u => [u.id, u])); return ids.map(id => userMap.get(id) || null); }),
postsByUserId: new DataLoader(async (userIds) => { const posts = await db.post.findMany({ where: { userId: { in: userIds } } }); return userIds.map(id => posts.filter(p => p.userId === id)); }), }; }
// ── Apollo Server with DataLoader in context ────────── const server = new ApolloServer({ typeDefs, resolvers: { User: { posts: (parent, _, { loaders }) => loaders.postsByUserId.load(parent.id), }, Post: { author: (parent, _, { loaders }) => loaders.userById.load(parent.userId), }, }, context: ({ req }) => ({ db: prisma, user: authenticate(req), loaders: createLoaders(prisma), // new loaders per request }), });
// ── GraphQL Subscriptions ─────────────────────────────
const resolvers = {
Subscription: {
messageAdded: {
subscribe: (_, { roomId }, { pubsub }) =>
pubsub.asyncIterator(MESSAGE_ADDED_${roomId}),
},
},
Mutation: {
sendMessage: async (_, { roomId, text }, { db, pubsub, user }) => {
const message = await db.message.create({
data: { roomId, text, userId: user.id }
});
await pubsub.publish(MESSAGE_ADDED_${roomId}, {
messageAdded: message
});
return message;
},
},
};
```
Explore the Full Portfolio
This is the complete portfolio of Sufi Khan Sulaiman, a technology leader specialising in B2B commerce and digital automation. Start from the Home page for the overview, then move through two decades of career experience across FLIR Systems, Lorex Technology, and 1c Platform, and the full catalogue of project case studies spanning headless commerce migrations, AI recommendation engines, and multi-channel fulfilment systems.
The skills and certifications page maps the technical and leadership capabilities behind the work, while the articles and the knowledge base break down the thinking into actionable frameworks. For hands-on learning, the tutorials and applications sections cover practical builds from front-end fundamentals to full-stack web apps.
For consulting engagement, the expertise page outlines service offerings, the ecommerce hub covers platform architecture and automation strategy, and the ecommerce guide (PDF) is a downloadable 55-page field manual. When you are ready to talk, the contact page is the direct line.