
Golang Graphql
Implement GraphQL resolvers in Go (gqlgen or graph-gophers) with correct DataLoader batching and N+1-safe database access.
Overview
golang-graphql is an agent skill for the Build phase that encodes Go GraphQL resolver and DataLoader rules for gqlgen and graph-gophers projects.
Install
npx skills add https://github.com/samber/cc-skills-golang --skill golang-graphqlWhat is this skill?
- Eval-driven guidance for gqlgen `User.posts` resolvers that must batch via per-request DataLoaders—not direct DB queries
- Requires DataLoader access from request context and HTTP middleware that instantiates loaders per request (no globals)
- Covers graph-gophers/graphql-go field resolvers such as `commentCount` on posts
- Emphasizes PostgreSQL-backed fetching patterns aligned with standard gqlgen project layout
- Assertions encode anti-patterns: no `db.Query` inside resolver bodies, no package-level loaders
- 2 documented eval scenarios (gqlgen User.posts, graph-gophers commentCount)
- 6+ explicit assertions on DataLoader and no-direct-DB rules in eval 1
Adoption & trust: 2k installs on skills.sh; 2k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your agent keeps writing GraphQL resolvers that hit PostgreSQL row-by-row and will N+1 under real load.
Who is it for?
Indie backend devs on gqlgen or graph-gophers with PostgreSQL who want agents to follow batch-loading discipline automatically.
Skip if: Greenfield GraphQL schema design from scratch, frontend GraphQL clients, or teams not using Go.
When should I use this skill?
Implementing or reviewing Go GraphQL resolvers, DataLoader middleware, or graph-gophers field methods with PostgreSQL.
What do I get? / Deliverables
Generated resolvers use per-request DataLoaders from context and field methods that satisfy the skill's eval assertions instead of ad-hoc DB access.
- Resolver functions matching eval signatures
- Per-request DataLoader wiring guidance
- Field resolvers for graph-gophers SDL fields
Recommended Skills
Journey fit
GraphQL schema and resolver work is core backend product construction during Build, before you ship API behavior to clients. Backend subphase is where API layers, resolvers, and data-loading patterns live for solo Go services.
How it compares
Go GraphQL resolver-quality guardrails with eval assertions—not a generic OpenAPI REST skill or a GraphQL schema-only generator.
Common Questions / FAQ
Who is golang-graphql for?
Solo builders maintaining Go GraphQL services with gqlgen or graph-gophers who need coding agents to respect DataLoader and resolver boundaries.
When should I use golang-graphql?
During Build backend work when adding relation resolvers (e.g., User.posts), computed fields, or middleware that must attach loaders per request.
Is golang-graphql safe to install?
It is procedural Go/GraphQL knowledge only; review the Security Audits panel on this page before trusting any third-party skill in production repos.
SKILL.md
READMESKILL.md - Golang Graphql
{ "skill_name": "golang-graphql", "evals": [ { "id": 1, "prompt": "I have a gqlgen project with a User type and a Post type. Users have many posts. Write the Go resolver for User.posts. We fetch posts from a PostgreSQL database. The project is set up with a standard gqlgen layout.", "expected_output": "A resolver that uses a per-request DataLoader (not direct DB calls) to batch-fetch posts by user IDs. Must NOT query the database directly inside the resolver. Must NOT use a global DataLoader. Should use context to access the per-request loader.", "assertions": [ "Uses a DataLoader or batch loader to fetch posts, not a direct db.Query/QueryContext call inside the resolver method", "Accesses the DataLoader from context (not a package-level or global variable)", "The resolver function signature uses obj *model.User as a parameter to access the parent user's ID", "Does not query the database directly inside the Posts resolver body", "Mentions that the DataLoader must be injected per-request via HTTP middleware", "DataLoader middleware creates a new loader instance per request, not a shared global" ], "files": [] }, { "id": 2, "prompt": "We have a graph-gophers/graphql-go project. I need to add a resolver that returns the total comment count for a post. The field is declared as `commentCount: Int!` in the SDL. Write the Go resolver method.", "expected_output": "Resolver method using int32 (not int) as the return type for the Int! scalar field. Must use int32, since graph-gophers requires this specific type.", "assertions": [ "Returns int32 (not int, int64, or uint) for the Int! scalar field", "Method signature matches the SDL field name (case-insensitive: CommentCount or commentCount)", "Does not return plain Go int — which causes a type mismatch at parse time with graph-gophers" ], "files": [] }, { "id": 3, "prompt": "Set up a production-ready gqlgen HTTP handler. The app will be deployed publicly. We need to make sure it's safe to expose.", "expected_output": "Handler setup that gates introspection (disabled or ENV-checked in production) and adds a query complexity limit. Must not leave introspection unconditionally enabled.", "assertions": [ "Introspection is gated — either disabled in production or guarded by an environment variable check", "A complexity limit is set using extension.FixedComplexityLimit or equivalent", "Does NOT call srv.Use(extension.Introspection{}) unconditionally without an env guard", "Uses handler.New or handler.NewDefaultServer from github.com/99designs/gqlgen/graphql/handler", "Mentions MaxDepth or complexity limiting as a protection against deeply nested queries" ], "files": [] }, { "id": 4, "prompt": "Implement a messageAdded subscription resolver in gqlgen. Messages are published via an in-memory pub/sub system. The resolver should stream new messages to subscribers in a given room.", "expected_output": "Subscription resolver that closes the channel on context cancellation (defer close(ch) + ctx.Done() in a select). Must handle client disconnect to avoid goroutine leaks.", "assertions": [ "Uses defer close(ch) to close the output channel when done", "Uses a select statement with ctx.Done() to detect client disconnection", "Returns a receive-only channel (<-chan *model.Message or similar)", "Does not use a plain for-range loop without ctx.Done() check — this would cause a goroutine leak on disconnect", "The goroutine terminates when ctx is cancelled" ], "files": [] }, { "id": 5, "prompt": "I'm using gqlgen and want to customize the User type to reuse my existing domain.User struct instead of having gqlgen generate a new one. The domain struct has an Email fiel