137 lines
4.8 KiB
Markdown
137 lines
4.8 KiB
Markdown
|
|
# CLAUDE.md
|
||
|
|
|
||
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||
|
|
|
||
|
|
## Project Overview
|
||
|
|
|
||
|
|
This is a GraphQL schema registry service that manages federated GraphQL schemas for microservices. It allows services to publish their subgraph schemas and provides merged supergraphs with Cosmo Router configuration for federated GraphQL gateways.
|
||
|
|
|
||
|
|
## Architecture
|
||
|
|
|
||
|
|
### Event Sourcing
|
||
|
|
The system uses event sourcing via `gitlab.com/unboundsoftware/eventsourced`. Key domain aggregates are:
|
||
|
|
- **Organization** (domain/aggregates.go): Manages organizations, users, and API keys
|
||
|
|
- **SubGraph** (domain/aggregates.go): Tracks subgraph schemas with versioning
|
||
|
|
|
||
|
|
All state changes flow through events (domain/events.go) and commands (domain/commands.go). The EventStore persists events to PostgreSQL, and events are published to RabbitMQ for downstream consumers.
|
||
|
|
|
||
|
|
### GraphQL Layer
|
||
|
|
- **Schema**: graph/schema.graphqls defines the API
|
||
|
|
- **Resolvers**: graph/schema.resolvers.go implements mutations/queries
|
||
|
|
- **Generated Code**: graph/generated/ and graph/model/ (auto-generated by gqlgen)
|
||
|
|
|
||
|
|
The resolver (graph/resolver.go) coordinates between the EventStore, Publisher (RabbitMQ), Cache, and PubSub for subscriptions.
|
||
|
|
|
||
|
|
### Schema Merging
|
||
|
|
The sdlmerge/ package handles GraphQL schema federation:
|
||
|
|
- Merges multiple subgraph SDL schemas into a unified supergraph
|
||
|
|
- Uses wundergraph/graphql-go-tools for AST manipulation
|
||
|
|
- Removes duplicates, extends types, and applies federation directives
|
||
|
|
|
||
|
|
### Authentication & Authorization
|
||
|
|
- **Auth0 JWT** (middleware/auth0.go): Validates user tokens from Auth0
|
||
|
|
- **API Keys** (middleware/apikey.go): Validates service API keys
|
||
|
|
- **Auth Middleware** (middleware/auth.go): Routes auth based on context
|
||
|
|
|
||
|
|
The @auth directive controls field-level access (user vs organization API key).
|
||
|
|
|
||
|
|
### Cosmo Router Integration
|
||
|
|
The service generates Cosmo Router configuration (graph/cosmo.go) using the wgc CLI tool installed in the Docker container. This config enables federated query execution across subgraphs.
|
||
|
|
|
||
|
|
### PubSub for Real-time Updates
|
||
|
|
graph/pubsub.go implements subscription support for schemaUpdates, allowing clients to receive real-time notifications when schemas change.
|
||
|
|
|
||
|
|
## Commands
|
||
|
|
|
||
|
|
### Code Generation
|
||
|
|
```bash
|
||
|
|
# Generate GraphQL server code (gqlgen), format, and organize imports
|
||
|
|
go generate ./...
|
||
|
|
```
|
||
|
|
|
||
|
|
Always run this after modifying graph/schema.graphqls. The go:generate directives are in:
|
||
|
|
- graph/resolver.go: runs gqlgen, gofumpt, and goimports
|
||
|
|
- ctl/ctl.go: generates genqlient client code
|
||
|
|
|
||
|
|
### Testing
|
||
|
|
```bash
|
||
|
|
# Run all tests
|
||
|
|
go test ./... -v
|
||
|
|
|
||
|
|
# Run tests with race detection and coverage (as used in CI)
|
||
|
|
CGO_ENABLED=1 go test -race -coverprofile=coverage.txt -covermode=atomic ./...
|
||
|
|
|
||
|
|
# Run specific package tests
|
||
|
|
go test ./middleware -v
|
||
|
|
go test ./graph -v -run TestGenerateCosmoRouterConfig
|
||
|
|
|
||
|
|
# Run single test
|
||
|
|
go test ./cmd/service -v -run TestWebSocket
|
||
|
|
```
|
||
|
|
|
||
|
|
### Building
|
||
|
|
```bash
|
||
|
|
# Build the service binary
|
||
|
|
go build -o service ./cmd/service/service.go
|
||
|
|
|
||
|
|
# Build the CLI tool
|
||
|
|
go build -o schemactl ./cmd/schemactl/schemactl.go
|
||
|
|
|
||
|
|
# Docker build (multi-stage)
|
||
|
|
docker build -t schemas .
|
||
|
|
```
|
||
|
|
|
||
|
|
The Dockerfile runs tests with coverage before building the production binary.
|
||
|
|
|
||
|
|
### Running the Service
|
||
|
|
```bash
|
||
|
|
# Start the service (requires PostgreSQL and RabbitMQ)
|
||
|
|
go run ./cmd/service/service.go \
|
||
|
|
--postgres-url="postgres://user:pass@localhost:5432/schemas?sslmode=disable" \
|
||
|
|
--amqp-url="amqp://user:pass@localhost:5672/" \
|
||
|
|
--issuer="your-auth0-domain.auth0.com"
|
||
|
|
|
||
|
|
# The service listens on port 8080 by default
|
||
|
|
# GraphQL Playground available at http://localhost:8080/
|
||
|
|
```
|
||
|
|
|
||
|
|
### Using the schemactl CLI
|
||
|
|
```bash
|
||
|
|
# Publish a subgraph schema
|
||
|
|
schemactl publish \
|
||
|
|
--api-key="your-api-key" \
|
||
|
|
--schema-ref="production" \
|
||
|
|
--service="users" \
|
||
|
|
--url="http://users-service:8080/query" \
|
||
|
|
--sdl=schema.graphql
|
||
|
|
|
||
|
|
# List subgraphs for a ref
|
||
|
|
schemactl list \
|
||
|
|
--api-key="your-api-key" \
|
||
|
|
--schema-ref="production"
|
||
|
|
```
|
||
|
|
|
||
|
|
## Development Workflow
|
||
|
|
|
||
|
|
1. **Schema Changes**: Edit graph/schema.graphqls → run `go generate ./...`
|
||
|
|
2. **Resolver Implementation**: Implement in graph/schema.resolvers.go
|
||
|
|
3. **Testing**: Write tests, run `go test ./...`
|
||
|
|
4. **Pre-commit**: Hooks run go-mod-tidy, goimports, gofumpt, golangci-lint, and tests
|
||
|
|
|
||
|
|
## Key Dependencies
|
||
|
|
|
||
|
|
- **gqlgen**: GraphQL server generation
|
||
|
|
- **genqlient**: GraphQL client generation (for ctl package)
|
||
|
|
- **eventsourced**: Event sourcing framework
|
||
|
|
- **wundergraph/graphql-go-tools**: Schema federation and composition
|
||
|
|
- **wgc CLI**: Cosmo Router config generation (Node.js tool)
|
||
|
|
- **Auth0**: JWT authentication
|
||
|
|
- **OpenTelemetry**: Observability (traces, metrics, logs)
|
||
|
|
|
||
|
|
## Important Files
|
||
|
|
|
||
|
|
- gqlgen.yml: gqlgen configuration
|
||
|
|
- graph/tools.go: Declares build-time tool dependencies
|
||
|
|
- .pre-commit-config.yaml: Pre-commit hooks configuration
|
||
|
|
- cliff.toml: Changelog generation config
|