> ## Documentation Index
> Fetch the complete documentation index at: https://docs.go-mizu.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Services

> Learn how to design interfaces and implementations for Contract - the foundation of your API

## The Interface-First Approach

In Contract, a **service** is defined by two parts:

1. **An interface** - Declares what operations your API supports (the "what")
2. **An implementation** - Contains the actual business logic (the "how")

This separation is intentional and powerful. The interface is your API contract - it's the source of truth for what your service can do. The implementation is a detail that clients don't need to know about.

We recommend organizing each service in its own Go package. This lets you use clean, simple names like `API` and `Service` - the package name provides the context:

```go theme={null}
package todo

import "context"

// API defines the contract for todo operations.
// When imported, this becomes "todo.API" which reads naturally.
type API interface {
    Create(ctx context.Context, in *CreateInput) (*Todo, error)
    List(ctx context.Context) (*ListOutput, error)
}

// Service implements todo.API with actual business logic.
// When imported, this becomes "todo.Service".
type Service struct {
    db *sql.DB  // Dependencies go here
}

func (s *Service) Create(ctx context.Context, in *CreateInput) (*Todo, error) {
    // Your business logic here
}
```

## Why Interface-First?

Before diving into the details, let's understand why this approach is valuable.

### Compile-Time Safety

If your implementation doesn't match the interface, Go's compiler tells you immediately - before your code even runs:

```go theme={null}
package todo

type API interface {
    Create(ctx context.Context, in *CreateInput) (*Todo, error)
}

type Service struct{}

// This won't compile!
// Error: cannot use &Service{} (type *Service) as type API
// missing method Create

// You can add a compile-time check explicitly:
var _ API = (*Service)(nil)  // Fails if Service doesn't implement API
```

The compiler catches mismatches before your code even runs. This is a huge advantage over dynamic approaches where you might only discover problems when users hit a bug in production.

### Clear Contracts

The interface IS your API documentation. Anyone can read it and understand exactly what your service does, without digging through implementation details:

```go theme={null}
package user

// API defines all operations for user management.
// Reading this interface tells you everything about what the service can do.
type API interface {
    // Create registers a new user account.
    // Returns the created user with a generated ID.
    Create(ctx context.Context, in *CreateInput) (*User, error)

    // Get retrieves a user by their unique ID.
    // Returns NOT_FOUND error if the user doesn't exist.
    Get(ctx context.Context, in *GetInput) (*User, error)

    // Update modifies an existing user's profile.
    // Only fields provided in the input are changed.
    Update(ctx context.Context, in *UpdateInput) (*User, error)

    // Delete removes a user account permanently.
    // This operation cannot be undone.
    Delete(ctx context.Context, in *DeleteInput) error

    // List returns all users with pagination support.
    List(ctx context.Context, in *ListInput) (*ListOutput, error)
}
```

### Easy Testing

Because the interface separates "what" from "how", you can easily create mock implementations for testing:

```go theme={null}
package user_test

import "yourapp/user"

// MockService implements user.API for testing.
// It stores users in memory instead of a real database.
type MockService struct {
    users map[string]*user.User
}

func (m *MockService) Get(ctx context.Context, in *user.GetInput) (*user.User, error) {
    if u, ok := m.users[in.ID]; ok {
        return u, nil
    }
    return nil, errors.New("not found")
}

func (m *MockService) Create(ctx context.Context, in *user.CreateInput) (*user.User, error) {
    u := &user.User{ID: "test-123", Email: in.Email}
    m.users[u.ID] = u
    return u, nil
}

// ... implement other methods

// Now use MockService in your tests!
func TestSomethingThatNeedsUsers(t *testing.T) {
    mock := &MockService{users: make(map[string]*user.User)}
    // Use mock instead of real service
}
```

### Multiple Implementations

You can have different implementations for different situations - all sharing the same interface:

```go theme={null}
package storage

// API defines storage operations.
// The same interface can have multiple implementations.
type API interface {
    Save(ctx context.Context, in *SaveInput) error
    Load(ctx context.Context, in *LoadInput) (*Data, error)
}

// FileService stores data on the local filesystem.
// Good for development and single-server deployments.
type FileService struct {
    basePath string
}

// S3Service stores data in Amazon S3.
// Good for production with multiple servers.
type S3Service struct {
    bucket string
    client *s3.Client
}

// MemoryService stores data in memory.
// Perfect for tests - fast and isolated.
type MemoryService struct {
    data map[string][]byte
}

// All three implement storage.API!
// Your application can switch between them based on configuration.
```

## Package Organization

We recommend organizing each service in its own package with a consistent structure:

```
yourapp/
├── main.go              # Wires everything together
├── todo/
│   ├── api.go           # Interface definition (todo.API)
│   ├── service.go       # Implementation (todo.Service)
│   └── types.go         # Input/output types
├── user/
│   ├── api.go           # Interface definition (user.API)
│   ├── service.go       # Implementation (user.Service)
│   └── types.go         # Input/output types
```

**Why this structure?**

1. **Package-based naming**: `todo.API` is clearer than `TodoAPI`, and `user.Service` is clearer than `userService`
2. **Encapsulation**: Each package is self-contained with its own types
3. **Discoverability**: Finding the todo API? Look in the `todo` package
4. **Scalability**: Adding a new service? Create a new package

## Defining Your Interface

### Basic Structure

Every interface method must follow specific patterns. The rules are straightforward:

```go theme={null}
package myservice

type API interface {
    // Every method MUST have ctx as the first parameter
    // This is required for timeouts, cancellation, and request-scoped values
    MethodName(ctx context.Context, ...) ...
}
```

### Method Signature Patterns

Contract supports four method patterns. Let's explore each one with detailed explanations.

#### Pattern 1: Input and Output

The most common pattern - receive data, return data:

```go theme={null}
func MethodName(ctx context.Context, in *InputType) (*OutputType, error)
```

**Breakdown:**

* `ctx context.Context` - Required first parameter for request context
* `in *InputType` - Pointer to a struct containing the input data
* `*OutputType` - Pointer to a struct containing the result
* `error` - Always the last return value; nil means success

**Example:**

```go theme={null}
package order

type API interface {
    // Create places a new order.
    // Input: order details (items, customer, shipping address)
    // Output: the created order with generated ID and totals
    Create(ctx context.Context, in *CreateInput) (*Order, error)

    // Get retrieves order details by ID.
    // Input: the order ID to look up
    // Output: full order information
    Get(ctx context.Context, in *GetInput) (*Order, error)

    // CalculateShipping determines shipping cost.
    // Input: destination and items
    // Output: available shipping options with prices
    CalculateShipping(ctx context.Context, in *ShippingInput) (*ShippingOutput, error)
}
```

**When to use:** Most CRUD operations, calculations, queries - any method that receives data and returns data.

#### Pattern 2: Output Only (No Input)

Return data without receiving any input parameters:

```go theme={null}
func MethodName(ctx context.Context) (*OutputType, error)
```

**Breakdown:**

* No input parameter beyond context
* Still returns output and error

**Example:**

```go theme={null}
package dashboard

type API interface {
    // GetStats returns current system statistics.
    // No input needed - just returns current stats.
    GetStats(ctx context.Context) (*StatsOutput, error)

    // ListAll returns all items without any filters.
    // Useful for small datasets or admin interfaces.
    ListAll(ctx context.Context) (*ListOutput, error)

    // Health returns detailed health information.
    // More detailed than a simple ping.
    Health(ctx context.Context) (*HealthOutput, error)
}
```

**When to use:** Listing all items, getting current status, dashboard data, health checks that return information.

#### Pattern 3: Input Only (No Output)

Accept input but return only success/failure:

```go theme={null}
func MethodName(ctx context.Context, in *InputType) error
```

**Breakdown:**

* Accepts input data
* Only returns error (nil means success)
* No meaningful data to return

**Example:**

```go theme={null}
package notification

type API interface {
    // Send delivers a notification to a user.
    // We don't need to return anything - just success/failure.
    Send(ctx context.Context, in *SendInput) error

    // Delete removes a notification by ID.
    // Nothing to return after deletion.
    Delete(ctx context.Context, in *DeleteInput) error

    // MarkAllRead marks all notifications as read for a user.
    // Fire-and-forget operation.
    MarkAllRead(ctx context.Context, in *MarkReadInput) error
}
```

**When to use:** Delete operations, fire-and-forget updates, operations where you only care about success/failure.

#### Pattern 4: No Input or Output

Just do something and report success/failure:

```go theme={null}
func MethodName(ctx context.Context) error
```

**Breakdown:**

* Only context as input
* Only error as output
* Simplest possible signature

**Example:**

```go theme={null}
package maintenance

type API interface {
    // Ping checks if the service is responsive.
    // Returns nil if healthy, error if not.
    Ping(ctx context.Context) error

    // Cleanup runs maintenance tasks.
    // No parameters needed, no results to return.
    Cleanup(ctx context.Context) error

    // CheckDB verifies database connectivity.
    // Simple health check that returns error if DB is down.
    CheckDB(ctx context.Context) error
}
```

**When to use:** Health checks, ping endpoints, administrative operations with no configuration.

## Defining Input and Output Types

Types define the shape of data that flows through your API. Good type design makes your API clear and easy to use.

### Input Types

Input types describe what clients send to your methods. They should only contain fields that clients actually need to provide:

```go theme={null}
package user

// CreateInput contains everything needed to create a new user.
// Notice we don't include ID - that's generated by the server.
type CreateInput struct {
    // Required fields - must be provided by the client
    Email    string `json:"email"`    // User's email address
    Password string `json:"password"` // Plain text (we'll hash it)
    Name     string `json:"name"`     // Display name

    // Optional fields - zero value if not provided
    Phone    string `json:"phone,omitempty"`  // "" if not sent
    Avatar   string `json:"avatar,omitempty"` // "" if not sent
}
```

**Key points:**

* Use pointer types in method signatures: `*CreateInput`
* Use `json` tags to control field names in JSON
* Add `omitempty` for optional fields (tells JSON encoder to skip empty values)
* Don't include server-generated fields (like ID, CreatedAt)

### Output Types

Output types describe what you return to clients. They can include computed and server-generated fields:

```go theme={null}
package user

// User represents a user in the system.
// This is what clients receive back from the API.
type User struct {
    ID        string    `json:"id"`        // Server-generated unique identifier
    Email     string    `json:"email"`     // From input
    Name      string    `json:"name"`      // From input
    CreatedAt time.Time `json:"createdAt"` // Server-generated timestamp
    UpdatedAt time.Time `json:"updatedAt"` // Server-managed timestamp
}

// ListOutput wraps a list of users with metadata.
// Wrapping in a struct lets us add pagination info.
type ListOutput struct {
    Users []*User `json:"users"` // The actual user data
    Total int     `json:"total"` // Total count for pagination
    Page  int     `json:"page"`  // Current page number
}
```

### Why Separate Input and Output Types?

You might wonder why we don't just use one `User` type everywhere. Here's why separation is valuable:

```go theme={null}
package todo

// BAD: Using same type for input and output
// Problems:
// - Clients might try to set ID (server-generated)
// - Clients might try to set CreatedAt (server-managed)
// - No way to distinguish required vs optional fields
type Todo struct {
    ID        string    `json:"id"`
    Title     string    `json:"title"`
    Completed bool      `json:"completed"`
    CreatedAt time.Time `json:"createdAt"`
}

// GOOD: Separate types for different purposes
// CreateInput - only what clients provide
type CreateInput struct {
    Title string `json:"title"` // Only field needed to create
}

// UpdateInput - what can be updated
type UpdateInput struct {
    ID        string `json:"id"`        // Which todo to update
    Title     string `json:"title"`     // Can change title
    Completed bool   `json:"completed"` // Can change status
}

// Todo - full representation with server data
type Todo struct {
    ID        string    `json:"id"`        // Server-generated
    Title     string    `json:"title"`     // From input
    Completed bool      `json:"completed"` // From input or default
    CreatedAt time.Time `json:"createdAt"` // Server-generated
    UpdatedAt time.Time `json:"updatedAt"` // Server-managed
}
```

### Nested Types

For complex data, nest types within each other. This creates clear, reusable structures:

```go theme={null}
package order

// Order represents a complete order with all its details.
type Order struct {
    ID       string     `json:"id"`
    Customer *Customer  `json:"customer"`  // Nested customer info
    Items    []*Item    `json:"items"`     // List of ordered items
    Shipping *Address   `json:"shipping"`  // Where to ship
    Billing  *Address   `json:"billing"`   // Billing address (can reuse Address)
    Total    Money      `json:"total"`     // Order total
}

// Customer contains customer information.
type Customer struct {
    ID    string `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

// Item represents one line item in an order.
type Item struct {
    ProductID string `json:"productId"`
    Name      string `json:"name"`
    Quantity  int    `json:"quantity"`
    Price     Money  `json:"price"`
}

// Address is a physical address.
// Reused for both shipping and billing.
type Address struct {
    Street  string `json:"street"`
    City    string `json:"city"`
    State   string `json:"state"`
    Country string `json:"country"`
    Zip     string `json:"zip"`
}

// Money represents a monetary amount.
type Money struct {
    Amount   int64  `json:"amount"`   // Amount in cents
    Currency string `json:"currency"` // ISO currency code
}
```

## Implementing Your Interface

Now let's implement the interface with actual business logic.

### Basic Implementation

Create a struct that implements all interface methods:

```go theme={null}
package todo

import (
    "context"
    "database/sql"
    "time"
)

// Service implements todo.API.
// It contains dependencies needed to perform operations.
type Service struct {
    db *sql.DB  // Database connection
}

// Compile-time check that Service implements API.
// If Service is missing methods, this line causes a compile error.
var _ API = (*Service)(nil)

// NewService creates a new todo Service with the given dependencies.
// This is the "constructor" - the standard Go pattern for creating instances.
func NewService(db *sql.DB) *Service {
    return &Service{db: db}
}

// Create implements todo.API.Create
func (s *Service) Create(ctx context.Context, in *CreateInput) (*Todo, error) {
    // Validate input
    if in.Title == "" {
        return nil, errors.New("title is required")
    }

    // Create the todo
    now := time.Now()
    todo := &Todo{
        ID:        generateID(),
        Title:     in.Title,
        Completed: false,
        CreatedAt: now,
        UpdatedAt: now,
    }

    // Save to database
    _, err := s.db.ExecContext(ctx,
        "INSERT INTO todos (id, title, completed, created_at, updated_at) VALUES (?, ?, ?, ?, ?)",
        todo.ID, todo.Title, todo.Completed, todo.CreatedAt, todo.UpdatedAt,
    )
    if err != nil {
        return nil, err
    }

    return todo, nil
}

// List implements todo.API.List
func (s *Service) List(ctx context.Context) (*ListOutput, error) {
    rows, err := s.db.QueryContext(ctx, "SELECT id, title, completed, created_at, updated_at FROM todos")
    if err != nil {
        return nil, err
    }
    defer rows.Close()

    var todos []*Todo
    for rows.Next() {
        t := &Todo{}
        if err := rows.Scan(&t.ID, &t.Title, &t.Completed, &t.CreatedAt, &t.UpdatedAt); err != nil {
            return nil, err
        }
        todos = append(todos, t)
    }

    return &ListOutput{
        Items: todos,
        Count: len(todos),
    }, nil
}

// ... implement other methods
```

### With Multiple Dependencies

Real services often need multiple dependencies. Inject them all through the constructor:

```go theme={null}
package user

import (
    "context"
    "database/sql"
    "log/slog"

    "github.com/redis/go-redis/v9"
)

// Service implements user.API with all required dependencies.
type Service struct {
    db     *sql.DB         // Primary database
    cache  *redis.Client   // Cache for frequent lookups
    mailer EmailSender     // For sending emails (interface for testability)
    logger *slog.Logger    // Structured logging
}

// EmailSender is an interface so we can mock it in tests.
type EmailSender interface {
    Send(ctx context.Context, to, subject, body string) error
}

// NewService creates a new user Service with all dependencies.
func NewService(
    db *sql.DB,
    cache *redis.Client,
    mailer EmailSender,
    logger *slog.Logger,
) *Service {
    return &Service{
        db:     db,
        cache:  cache,
        mailer: mailer,
        logger: logger,
    }
}

func (s *Service) Create(ctx context.Context, in *CreateInput) (*User, error) {
    s.logger.Info("creating user", "email", in.Email)

    // Create user in database
    user := &User{ID: generateID(), Email: in.Email, Name: in.Name}
    if err := s.saveToDatabase(ctx, user); err != nil {
        s.logger.Error("failed to save user", "error", err)
        return nil, err
    }

    // Cache the user for fast lookups
    if err := s.cacheUser(ctx, user); err != nil {
        s.logger.Warn("failed to cache user", "error", err)
        // Don't fail the request - caching is optional
    }

    // Send welcome email
    if err := s.mailer.Send(ctx, user.Email, "Welcome!", "Thanks for signing up!"); err != nil {
        s.logger.Warn("failed to send welcome email", "error", err)
        // Don't fail the request - email is best-effort
    }

    return user, nil
}
```

### Compile-Time Interface Check

Always add a compile-time check to ensure your implementation is complete. This catches missing methods immediately:

```go theme={null}
package todo

type API interface {
    Create(ctx context.Context, in *CreateInput) (*Todo, error)
    List(ctx context.Context) (*ListOutput, error)
    Get(ctx context.Context, in *GetInput) (*Todo, error)
    Delete(ctx context.Context, in *DeleteInput) error
}

type Service struct {
    db *sql.DB
}

// This line is a compile-time assertion.
// If Service doesn't implement all methods of API, compilation fails.
// The syntax works because:
// - (*Service)(nil) creates a nil pointer of type *Service
// - var _ API = ... checks if that pointer satisfies the API interface
var _ API = (*Service)(nil)

// Now implement the methods...
func (s *Service) Create(ctx context.Context, in *CreateInput) (*Todo, error) {
    // ...
}
```

If you forget to implement a method, you'll see a clear error:

```
cannot use (*Service)(nil) (type *Service) as type API in assignment:
    *Service does not implement API (missing Delete method)
```

## Method Naming Conventions

Method names affect how they're exposed via REST. Contract uses naming conventions to determine HTTP methods:

| Method Name Pattern     | REST Endpoint          | HTTP Method |
| ----------------------- | ---------------------- | ----------- |
| `Create`, `Add`, `New`  | `/{resource}`          | POST        |
| `List`, `All`, `Search` | `/{resource}`          | GET         |
| `Get`, `Find`, `Fetch`  | `/{resource}/{id}`     | GET         |
| `Update`, `Edit`, `Set` | `/{resource}/{id}`     | PUT         |
| `Delete`, `Remove`      | `/{resource}/{id}`     | DELETE      |
| `Patch`                 | `/{resource}/{id}`     | PATCH       |
| Other names             | `/{resource}/{action}` | POST        |

**Examples:**

```go theme={null}
package product

type API interface {
    Create(...)     // POST   /products         - Create new product
    List(...)       // GET    /products         - List all products
    Get(...)        // GET    /products/{id}    - Get one product
    Update(...)     // PUT    /products/{id}    - Update product
    Delete(...)     // DELETE /products/{id}    - Delete product
    Search(...)     // GET    /products         - Search (with query params)
    Archive(...)    // POST   /products/archive - Custom action
}
```

## Using Context

Every method receives `context.Context` as its first parameter. Context is Go's standard way to pass request-scoped data and control request lifecycle.

### Cancellation

Check if the client cancelled the request. This is important for long-running operations:

```go theme={null}
func (s *Service) ProcessLargeDataset(ctx context.Context, in *ProcessInput) (*Output, error) {
    for i, item := range in.Items {
        // Check if context was cancelled before each item
        if err := ctx.Err(); err != nil {
            // Client disconnected or timeout occurred
            return nil, err
        }

        // Process the item
        if err := s.processItem(ctx, item); err != nil {
            return nil, err
        }
    }
    return &Output{ProcessedCount: len(in.Items)}, nil
}
```

### Timeouts

Pass context to database and external calls. The context carries timeout information:

```go theme={null}
func (s *Service) Get(ctx context.Context, in *GetInput) (*Todo, error) {
    // The context timeout is automatically respected by the database driver
    row := s.db.QueryRowContext(ctx, "SELECT * FROM todos WHERE id = $1", in.ID)

    todo := &Todo{}
    err := row.Scan(&todo.ID, &todo.Title, &todo.Completed)
    if err == sql.ErrNoRows {
        return nil, contract.ErrNotFound("todo not found")
    }
    return todo, err
}
```

### Request-Scoped Values

Access values set by middleware (like authenticated user):

```go theme={null}
// Key type for context values (prevents collisions)
type contextKey string

const userIDKey contextKey = "userID"

func (s *Service) Create(ctx context.Context, in *CreateInput) (*Todo, error) {
    // Get authenticated user ID from context (set by auth middleware)
    userID, ok := ctx.Value(userIDKey).(string)
    if !ok {
        return nil, contract.ErrUnauthenticated("not logged in")
    }

    // Use userID in your logic
    todo := &Todo{
        ID:      generateID(),
        Title:   in.Title,
        OwnerID: userID,  // Associate todo with the user
    }

    // Save and return
    return s.saveTodo(ctx, todo)
}
```

## Complete Example

Here's a complete, production-ready service demonstrating all the concepts:

```go theme={null}
// user/types.go
package user

import "time"

// User represents a user in the system.
type User struct {
    ID        string    `json:"id"`
    Email     string    `json:"email"`
    Name      string    `json:"name"`
    CreatedAt time.Time `json:"createdAt"`
    UpdatedAt time.Time `json:"updatedAt"`
}

// CreateInput contains data needed to create a user.
type CreateInput struct {
    Email string `json:"email"`
    Name  string `json:"name"`
}

// GetInput identifies which user to retrieve.
type GetInput struct {
    ID string `json:"id"`
}

// UpdateInput contains data for updating a user.
type UpdateInput struct {
    ID   string `json:"id"`
    Name string `json:"name"`
}

// DeleteInput identifies which user to delete.
type DeleteInput struct {
    ID string `json:"id"`
}

// ListInput contains pagination parameters.
type ListInput struct {
    Limit  int `json:"limit"`
    Offset int `json:"offset"`
}

// ListOutput contains paginated user results.
type ListOutput struct {
    Users []*User `json:"users"`
    Total int     `json:"total"`
}
```

```go theme={null}
// user/api.go
package user

import "context"

// API defines all user management operations.
type API interface {
    // Create registers a new user account.
    Create(ctx context.Context, in *CreateInput) (*User, error)

    // Get retrieves a user by ID.
    Get(ctx context.Context, in *GetInput) (*User, error)

    // Update modifies a user's profile.
    Update(ctx context.Context, in *UpdateInput) (*User, error)

    // Delete removes a user account.
    Delete(ctx context.Context, in *DeleteInput) error

    // List returns users with pagination.
    List(ctx context.Context, in *ListInput) (*ListOutput, error)
}
```

```go theme={null}
// user/service.go
package user

import (
    "context"
    "database/sql"
    "time"

    "github.com/google/uuid"
    contract "github.com/go-mizu/mizu/contract/v2"
)

// Service implements user.API.
type Service struct {
    db *sql.DB
}

// Compile-time interface check.
var _ API = (*Service)(nil)

// NewService creates a new user Service.
func NewService(db *sql.DB) *Service {
    return &Service{db: db}
}

func (s *Service) Create(ctx context.Context, in *CreateInput) (*User, error) {
    // Validate input
    if in.Email == "" {
        return nil, contract.ErrInvalidArgument("email is required")
    }
    if in.Name == "" {
        return nil, contract.ErrInvalidArgument("name is required")
    }

    // Create user
    now := time.Now()
    user := &User{
        ID:        uuid.New().String(),
        Email:     in.Email,
        Name:      in.Name,
        CreatedAt: now,
        UpdatedAt: now,
    }

    // Save to database
    _, err := s.db.ExecContext(ctx,
        "INSERT INTO users (id, email, name, created_at, updated_at) VALUES ($1, $2, $3, $4, $5)",
        user.ID, user.Email, user.Name, user.CreatedAt, user.UpdatedAt,
    )
    if err != nil {
        return nil, err
    }

    return user, nil
}

func (s *Service) Get(ctx context.Context, in *GetInput) (*User, error) {
    user := &User{}
    err := s.db.QueryRowContext(ctx,
        "SELECT id, email, name, created_at, updated_at FROM users WHERE id = $1",
        in.ID,
    ).Scan(&user.ID, &user.Email, &user.Name, &user.CreatedAt, &user.UpdatedAt)

    if err == sql.ErrNoRows {
        return nil, contract.ErrNotFound("user not found")
    }
    if err != nil {
        return nil, err
    }

    return user, nil
}

func (s *Service) Update(ctx context.Context, in *UpdateInput) (*User, error) {
    now := time.Now()

    result, err := s.db.ExecContext(ctx,
        "UPDATE users SET name = $1, updated_at = $2 WHERE id = $3",
        in.Name, now, in.ID,
    )
    if err != nil {
        return nil, err
    }

    rows, _ := result.RowsAffected()
    if rows == 0 {
        return nil, contract.ErrNotFound("user not found")
    }

    return s.Get(ctx, &GetInput{ID: in.ID})
}

func (s *Service) Delete(ctx context.Context, in *DeleteInput) error {
    result, err := s.db.ExecContext(ctx, "DELETE FROM users WHERE id = $1", in.ID)
    if err != nil {
        return err
    }

    rows, _ := result.RowsAffected()
    if rows == 0 {
        return contract.ErrNotFound("user not found")
    }

    return nil
}

func (s *Service) List(ctx context.Context, in *ListInput) (*ListOutput, error) {
    // Default limit
    limit := in.Limit
    if limit <= 0 {
        limit = 10
    }

    // Query users
    rows, err := s.db.QueryContext(ctx,
        "SELECT id, email, name, created_at, updated_at FROM users LIMIT $1 OFFSET $2",
        limit, in.Offset,
    )
    if err != nil {
        return nil, err
    }
    defer rows.Close()

    var users []*User
    for rows.Next() {
        user := &User{}
        if err := rows.Scan(&user.ID, &user.Email, &user.Name, &user.CreatedAt, &user.UpdatedAt); err != nil {
            return nil, err
        }
        users = append(users, user)
    }

    // Get total count
    var total int
    s.db.QueryRowContext(ctx, "SELECT COUNT(*) FROM users").Scan(&total)

    return &ListOutput{
        Users: users,
        Total: total,
    }, nil
}
```

## Best Practices

### Keep Services Focused

Each service should handle one domain. Don't create "god services" that do everything:

```go theme={null}
// GOOD: Focused services, one domain each
package todo    // type API interface { Create, List, Get, Delete }
package user    // type API interface { Create, Get, Update, Delete }
package order   // type API interface { Create, Get, List, Cancel }

// BAD: One giant service doing everything
package api
type EverythingAPI interface {
    CreateTodo(...)
    CreateUser(...)
    CreateOrder(...)
    // 50 more methods from different domains...
}
```

### Use Clear, Consistent Naming

Names should be descriptive and follow a consistent pattern:

```go theme={null}
// GOOD: Clear and consistent naming
package subscription

type API interface {
    Create(ctx context.Context, in *CreateInput) (*Subscription, error)
    Get(ctx context.Context, in *GetInput) (*Subscription, error)
    Cancel(ctx context.Context, in *CancelInput) error
    Renew(ctx context.Context, in *RenewInput) (*Subscription, error)
}

// BAD: Vague and inconsistent naming
package sub

type SubAPI interface {
    MakeSub(ctx context.Context, in *Input) (*Output, error)
    FetchSubscription(ctx context.Context, in *GetInput) (*Sub, error)
    DoCancel(ctx context.Context, in *CancelInput) error
}
```

### Inject Dependencies

Pass dependencies through the constructor, never use globals:

```go theme={null}
// GOOD: Dependency injection through constructor
type Service struct {
    db    Database
    cache Cache
}

func NewService(db Database, cache Cache) *Service {
    return &Service{db: db, cache: cache}
}

// BAD: Global dependencies
var globalDB *sql.DB  // DON'T DO THIS

func (s *Service) Create(...) {
    globalDB.Query(...)  // Untestable, hidden dependency
}
```

### Keep Business Logic in the Implementation

The interface should only declare operations. All logic goes in the implementation:

```go theme={null}
// Interface: Pure contract, no logic
type API interface {
    ProcessPayment(ctx context.Context, in *PaymentInput) (*Payment, error)
}

// Implementation: All the business logic
func (s *Service) ProcessPayment(ctx context.Context, in *PaymentInput) (*Payment, error) {
    // 1. Validation
    if in.Amount <= 0 {
        return nil, contract.ErrInvalidArgument("amount must be positive")
    }

    // 2. Business rules
    fee := s.calculateFee(in.Amount)
    total := in.Amount + fee

    // 3. External integrations
    chargeResult, err := s.stripe.Charge(ctx, in.CardToken, total)
    if err != nil {
        return nil, fmt.Errorf("payment failed: %w", err)
    }

    // 4. Persistence
    payment := &Payment{
        ID:     chargeResult.ID,
        Amount: in.Amount,
        Fee:    fee,
        Status: "completed",
    }
    if err := s.db.SavePayment(ctx, payment); err != nil {
        return nil, err
    }

    return payment, nil
}
```

## Common Questions

### Can I have multiple return values?

No, methods can only return `(*Output, error)` or `error`. If you need to return multiple values, wrap them in a struct:

```go theme={null}
// Instead of: func Get() (*User, *Profile, error)  // NOT SUPPORTED
// Use a wrapper struct:

type GetUserResult struct {
    User    *User    `json:"user"`
    Profile *Profile `json:"profile"`
}

func (s *Service) GetUser(ctx context.Context, in *GetInput) (*GetUserResult, error) {
    user, err := s.getUser(ctx, in.ID)
    if err != nil {
        return nil, err
    }
    profile, err := s.getProfile(ctx, in.ID)
    if err != nil {
        return nil, err
    }
    return &GetUserResult{User: user, Profile: profile}, nil
}
```

### Should input types be pointers?

Yes, always use pointers in the method signature:

```go theme={null}
// GOOD - use pointers
func (s *Service) Create(ctx context.Context, in *CreateInput) (*Output, error)

// BAD - don't use value types
func (s *Service) Create(ctx context.Context, in CreateInput) (Output, error)
```

Contract requires pointers for proper JSON unmarshaling and to support nil inputs.

### How do I handle optional fields?

Fields not provided by clients will have their zero value. For most cases, this works fine:

```go theme={null}
type UpdateInput struct {
    ID    string `json:"id"`    // Required - must be provided
    Title string `json:"title"` // Optional - "" if not sent
    Count int    `json:"count"` // Optional - 0 if not sent
}
```

For fields where you need to distinguish "not sent" from "sent as empty/zero", use pointers:

```go theme={null}
type UpdateInput struct {
    ID    string  `json:"id"`
    Title *string `json:"title"` // nil = not sent, "" = sent as empty
    Count *int    `json:"count"` // nil = not sent, 0 = sent as zero
}

func (s *Service) Update(ctx context.Context, in *UpdateInput) (*Todo, error) {
    todo, _ := s.Get(ctx, &GetInput{ID: in.ID})

    // Only update if field was explicitly sent
    if in.Title != nil {
        todo.Title = *in.Title
    }
    if in.Count != nil {
        todo.Count = *in.Count
    }

    return s.save(ctx, todo)
}
```

## What's Next?

Now that you know how to define services:

* **[Registration](/contract/register)** - How to register your service with Contract
* **[Error Handling](/contract/errors)** - Handle errors consistently across protocols
* **[Type System](/contract/types)** - Deep dive into type conversion and schemas
* **[Testing](/contract/testing)** - Test your services effectively
