encore-go-service

Par encoredev · skills

Structurez vos services avec Encore Go.

npx skills add https://github.com/encoredev/skills --skill encore-go-service

Structure de Service Encore Go

Instructions

Dans Encore Go, chaque package avec un endpoint API est automatiquement un service. Aucune configuration spéciale nécessaire.

Créer un Service

Créez simplement un package avec au moins un endpoint //encore:api :

// user/user.go
package user

import "context"

type User struct {
    ID    string `json:"id"`
    Email string `json:"email"`
    Name  string `json:"name"`
}

//encore:api public method=GET path=/users/:id
func GetUser(ctx context.Context, params *GetUserParams) (*User, error) {
    // Cela fait de "user" un service
}

Structure Minimale de Service

user/
├── user.go          # API endpoints
├── db.go            # Base de données (si nécessaire)
└── migrations/      # Migrations SQL
    └── 1_create_users.up.sql

Modèles d'Application

Service Unique (Recommandé au Démarrage)

Idéal pour les nouveaux projets - commencez simplement, divisez si nécessaire :

my-app/
├── encore.app
├── go.mod
├── api.go           # Tous les endpoints
├── db.go            # Base de données
└── migrations/
    └── 1_initial.up.sql

Multi-Service

Pour les systèmes distribués avec des limites de domaine claires :

my-app/
├── encore.app
├── go.mod
├── user/
│   ├── user.go
│   ├── db.go
│   └── migrations/
├── order/
│   ├── order.go
│   ├── db.go
│   └── migrations/
└── notification/
    └── notification.go

Application Large (Basée sur Systèmes)

Groupez les services connexes dans des systèmes :

my-app/
├── encore.app
├── go.mod
├── commerce/
│   ├── order/
│   │   └── order.go
│   ├── cart/
│   │   └── cart.go
│   └── payment/
│       └── payment.go
├── identity/
│   ├── user/
│   │   └── user.go
│   └── auth/
│       └── auth.go
└── comms/
    ├── email/
    │   └── email.go
    └── push/
        └── push.go

Appels Service-to-Service

Importez et appelez la fonction directement - Encore gère le RPC :

package order

import (
    "context"
    "myapp/user"  // Importer le service user
)

//encore:api auth method=GET path=/orders/:id
func GetOrderWithUser(ctx context.Context, params *GetOrderParams) (*OrderWithUser, error) {
    order, err := getOrder(ctx, params.ID)
    if err != nil {
        return nil, err
    }

    // Cela devient un appel RPC - Encore le gère
    orderUser, err := user.GetUser(ctx, &user.GetUserParams{ID: order.UserID})
    if err != nil {
        return nil, err
    }

    return &OrderWithUser{Order: order, User: orderUser}, nil
}

Quand Diviser les Services

Divisez quand vous avez :

Signal Action
Besoins de scaling différents Diviser (ex. authentification vs analytics)
Cycles de déploiement différents Diviser
Limites de domaine claires Diviser
Tables de base de données partagées Garder ensemble
Logique étroitement couplée Garder ensemble
Juste organiser le code Utiliser des sous-packages, pas des services

Helpers Internes (Packages Non-Service)

Créez des packages sans endpoints //encore:api pour le code partagé :

my-app/
├── user/
│   └── user.go       # Service (a une API)
├── order/
│   └── order.go      # Service (a une API)
└── internal/
    ├── util/
    │   └── util.go   # Pas un service (pas d'API)
    └── validation/
        └── validate.go

Recommandations

  • Un package devient un service quand il a des endpoints //encore:api
  • Les services ne peuvent pas être imbriqués dans d'autres services
  • Commencez avec un service, divisez quand il y a une raison claire
  • Les appels cross-service ressemblent à des appels de fonction ordinaires
  • Chaque service peut avoir sa propre base de données
  • Les noms de packages doivent être en minuscules, descriptifs
  • Ne créez pas de services juste pour organiser le code - utilisez des sous-packages à la place

Skills similaires