Claude Skills Guide

Claude Code for Strawberry GraphQL Workflow Guide

Strawberry GraphQL has emerged as one of the most popular Python libraries for building type-safe GraphQL APIs. Its decorator-based approach and native type hints integration make it a developer-friendly choice for Python projects. When combined with Claude Code, you get a powerful workflow that accelerates development while maintaining code quality. This guide walks you through integrating Claude Code into your Strawberry GraphQL projects for maximum productivity.

Why Strawberry GraphQL with Claude Code?

Strawberry GraphQL distinguishes itself from other Python GraphQL libraries through its modern approach. Unlike older libraries that require manual type definitions, Strawberry leverages Python’s type hints to automatically generate GraphQL schemas. This means less boilerplate code and fewer opportunities for inconsistencies between your Python types and GraphQL schema.

When you add Claude Code to this mix, you gain an AI assistant that understands both Python type systems and GraphQL schema design. Claude Code can help you:

The combination is particularly powerful for teams working on Python backends who want to ship GraphQL APIs faster without sacrificing type safety.

Setting Up Your Strawberry GraphQL Project

Start by creating a new Python project or navigating to your existing Strawberry project. If you’re starting fresh, here’s a quick setup:

mkdir strawberry-api && cd strawberry-api
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
pip install strawberry-graphql[fastapi] httpx

Now create your first Strawberry schema. Let me show you a practical example with a blog system:

# schema.py
import strawberry
from typing import List, Optional
from datetime import datetime

@strawberry.type
class Author:
    id: strawberry.ID
    name: str
    email: str
    bio: Optional[str] = None

@strawberry.type
class Post:
    id: strawberry.ID
    title: str
    content: str
    published_at: datetime
    author: Author
    tags: List[str]

@strawberry.type
class Query:
    @strawberry.field
    def hello(self) -> str:
        return "Hello, Strawberry!"

    @strawberry.field
    def posts(self) -> List[Post]:
        # In production, this would fetch from your database
        return [
            Post(
                id="1",
                title="Getting Started with Strawberry",
                content="Strawberry makes GraphQL in Python delightful...",
                published_at=datetime.now(),
                author=Author(id="1", name="Jane Doe", email="jane@example.com"),
                tags=["graphql", "python"]
            )
        ]

schema = strawberry.Schema(query=Query)

This schema demonstrates Strawberry’s clean type-based approach. Each @strawberry.type automatically generates a corresponding GraphQL type. The type hints become the schema definition—no separate SDL needed.

Leveraging Claude Code for Schema Development

When working on more complex schemas, Claude Code becomes invaluable. You can describe your data models and let Claude help generate the appropriate Strawberry types:

“Create a Strawberry GraphQL schema for an e-commerce system with products, categories, orders, and customers. Include proper relationships and pagination support.”

Claude Code will generate the complete schema with proper type annotations:

@strawberry.input
class ProductInput:
    name: str
    price: float
    category_id: strawberry.ID

@strawberry.input
class OrderItemInput:
    product_id: strawberry.ID
    quantity: int

@strawberry.input
class CreateOrderInput:
    customer_id: strawberry.ID
    items: List[OrderItemInput]
    shipping_address: str

@strawberry.type
class Order:
    id: strawberry.ID
    customer: Customer
    items: List[OrderItem]
    total: float
    status: str
    created_at: datetime
    
    @strawberry.field
    def total(self) -> float:
        return sum(item.price * item.quantity for item in self.items)

Notice how @strawberry.input creates input types for mutations, while @strawberry.type defines output types. This separation is crucial for building robust APIs.

Implementing Resolvers and Data Access

Resolvers in Strawberry can be defined as methods on types or as standalone functions. Here’s how to implement proper resolver patterns:

@strawberry.type
class Post:
    id: strawberry.ID
    title: str
    content: str
    author: "Author"
    
    @strawberry.field
    async def author(self, info: strawberry.Info) -> Author:
        # Access resolver-level data loading here
        return await info.context["authors"].load(self.id)

For database integration, Strawberry works seamlessly with ORMs like SQLAlchemy, Django ORM, or Tortoise. Here’s an example with SQLAlchemy:

import strawberry
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, declarative_base

Base = declarative_base()

class AuthorModel(Base):
    __tablename__ = "authors"
    id = Column(Integer, primary_key=True)
    name = Column(String)
    email = Column(String)

@strawberry.type
class Author:
    id: strawberry.ID
    name: str
    email: str
    
    @classmethod
    def from_model(cls, model: AuthorModel) -> "Author":
        return cls(id=strawberry.ID(str(model.id)), name=model.name, email=model.email)

@strawberry.type
class Query:
    @strawberry.field
    def authors(self) -> List[Author]:
        models = session.query(AuthorModel).all()
        return [Author.from_model(m) for m in models]

The key insight is creating from_model class methods that bridge your database models to GraphQL types. This pattern keeps your schema clean and testable.

Real-Time with Subscriptions

Strawberry supports subscriptions for real-time updates. Here’s how to implement a subscription that notifies when new posts are published:

import asyncio
import strawberry
from typing import AsyncIterator

@strawberry.type
class Post:
    id: strawberry.ID
    title: str
    content: str

@strawberry.type
class Subscription:
    @strawberry.subscription
    async def on_new_post(self, info: strawberry.Info) -> AsyncIterator[Post]:
        # This would connect to your pub/sub system (Redis, etc.)
        async for post in pubsub.subscribe("new_posts"):
            yield post

# In your mutation, publish the event:
@strawberry.mutation
async def create_post(self, title: str, content: str, info: strawberry.Info) -> Post:
    post = await save_post(title, content)
    await pubsub.publish("new_posts", post)
    return post

Subscriptions require an ASGI server that supports WebSocket connections, such as uvicorn with the proper configuration.

Production Best Practices

When deploying Strawberry GraphQL to production, consider these practices:

Use DataLoaders to Prevent N+1 Queries

from strawberry.dataloader import DataLoader

async def load_authors(post_ids: List[int]) -> List[Author]:
    # Batch fetch all authors for the given post IDs
    authors = await db.authors.where(post_id__in=post_ids).all()
    return authors

@strawberry.type
class Query:
    @strawberry.field
    async def posts(self, info: strawberry.Info) -> List[Post]:
        info.context["authors"] = DataLoader(load_authors)
        # Now posts can safely access author without N+1 queries

Add Query Cost Analysis

from strawberry.extensions import QueryDepthLimiter

schema = strawberry.Schema(
    query=Query,
    extensions=[QueryDepthLimiter(max_depth=3)]
)

Configure CORS Properly

from strawberry import strawberry
from strawberry.cors import CorsConfig

cors_config = CorsConfig(
    allow_origins=["https://yourfrontend.com"],
    allow_methods=["POST", "GET", "OPTIONS"],
)

app = strawberry.fastapi.router(schema, cors=cors_config)

Testing Your Strawberry API

Claude Code can help you write comprehensive tests. Here’s a testing pattern using httpx:

import pytest
from httpx import AsyncClient
from strawberry import strawberry as Strawberry

@pytest.fixture
async def client():
    from your_schema import schema
    async with AsyncClient(app=schema, base_url="http://test") as ac:
        yield ac

@pytest.mark.asyncio
async def test_query_posts(client):
    query = """
        query {
            posts {
                id
                title
                author {
                    name
                }
            }
        }
    """
    response = await client.post("/graphql", json={"query": query})
    assert response.status_code == 200
    data = response.json()["data"]
    assert len(data["posts"]) > 0

Conclusion

Strawberry GraphQL combined with Claude Code creates a powerful development workflow for Python developers. The type-safe nature of Strawberry aligns perfectly with Claude Code’s ability to understand and generate correct code. By following the patterns in this guide—proper type definitions, async resolvers, data loaders for performance, and comprehensive testing—you’ll build production-ready GraphQL APIs efficiently.

Remember to leverage Claude Code throughout your development process, from initial schema design to debugging and optimization. The AI assistance lets you focus on business logic while maintaining high code quality standards.

Built by theluckystrike — More at zovo.one