Go e Dapr: Distributed Application Runtime

Simplifique microsserviços com Dapr em Go. Aprenda service invocation, state management, pub/sub e bindings com exemplos práticos.

Go e Dapr: Distributed Application Runtime

Dapr (Distributed Application Runtime) é uma plataforma portátil e event-driven que facilita a construção de aplicações distribuídas e microsserviços. Projetado pela Microsoft, é usado por empresas como Alibaba, Tencent e Ignition Group.

Neste guia, você aprenderá a usar Dapr com Go para resolver desafios comuns de microsserviços de forma simples e portátil.

Índice

  1. O que é Dapr?
  2. Arquitetura e Sidecar
  3. Configuração
  4. Service Invocation
  5. State Management
  6. Pub/Sub Messaging
  7. Bindings
  8. Observability

O que é Dapr?

Building Blocks

Dapr fornece 8 building blocks que resolvem problemas comuns:

Ler mais →

Go e Temporal: Workflows Resilientes e Duráveis

Construa workflows resilientes com Temporal em Go. Aprenda about retries, sagas, signals e padrões de orquestração de processos distribuídos.

Go e Temporal: Workflows Resilientes e Duráveis

Temporal é uma plataforma de orquestração de workflows que permite criar processos de negócio resilientes, duráveis e escaláveis. Desenvolvido pelos criadores do Cadence (Uber), é amplamente adotado por empresas como Netflix, Stripe e Shopify.

Neste guia, você aprenderá a construir workflows complexos em Go com garantias de execução, retries automáticos e compensação (Saga pattern).

Índice

  1. Conceitos Fundamentais
  2. Configuração do Ambiente
  3. Primeiro Workflow
  4. Activities e Retries
  5. Saga Pattern
  6. Signals e Queries
  7. Timers e Cron Jobs
  8. Padrões Avançados

Conceitos Fundamentais

Arquitetura Temporal

┌─────────────────────────────────────────────────────────────┐
│                   Temporal Server                          │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐      │
│  │  Frontend    │  │   History    │  │   Matching   │      │
│  │   (gRPC)     │  │   (Events)   │  │   (Tasks)    │      │
│  └──────────────┘  └──────────────┘  └──────────────┘      │
│                                                             │
│  Persistence: PostgreSQL / MySQL / Cassandra / Elasticsearch│
└─────────────────────────────────────────────────────────────┘
           │ gRPC
┌─────────────────────────────────────────────────────────────┐
│                   Workers (Go)                             │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐      │
│  │   Workflow   │  │   Activity   │  │   Activity   │      │
│  │   Engine     │  │   Executor   │  │   Executor   │      │
│  └──────────────┘  └──────────────┘  └──────────────┘      │
│                                                             │
│  Workflows são determinísticos (replayable)                │
│  Activities contêm side-effects (I/O, APIs)                │
└─────────────────────────────────────────────────────────────┘

Conceitos Chave

Workflows: Funções Go que definem a lógica de negócio. São determinísticas e podem ser “replayed” indefinidamente.

Ler mais →

Go e gRPC: Comunicação entre Serviços Completo

Aprenda a criar APIs eficientes com gRPC em Go. Tutorial completo cobrindo Protocol Buffers, streaming, interceptores e testes.

Go e gRPC: Comunicação entre Serviços

O gRPC tornou-se o padrão de facto para comunicação entre microserviços em ambientes de alta performance. Desenvolvido pelo Google, ele oferece vantagens significativas sobre REST tradicional, especialmente quando combinado com a eficiência do Go.

Neste tutorial completo, você vai aprender a construir serviços gRPC robustos em Go, desde o básico até técnicas avançadas como streaming bidirecional e interceptores.

Por Que Usar gRPC em Go?

gRPC vs REST: Comparativo

CaracterísticaREST/HTTP JSONgRPC
FormatoJSON (texto)Protocol Buffers (binário)
Performance~15x mais lento~15x mais rápido
PayloadVerbos, repetitivoCompacto, eficiente
TipagemFraca (runtime)Forte (compile-time)
StreamingComplicado (SSE/WebSocket)Nativo e simples
Code GenerationManualAutomático
Browser SupportNativoRequer gRPC-Web

Quando escolher gRPC:

Ler mais →

Go para Microserviços: Arquitetura e Práticas de Produção

Domine a arquitetura de microserviços em Go. Aprenda padrões de comunicação, service discovery, circuit breakers, distributed tracing e estratégias de deploy com exemplos práticos.

Microserviços transformaram a forma como desenvolvemos sistemas escaláveis. Go é a linguagem preferida para microserviços em empresas como Netflix, Uber, e Kubernetes. Neste guia completo, você aprenderá a arquitetar, construir e operar microserviços robustos em Go.

Por Que Go é Perfeito para Microserviços

O Match Perfeito

┌─────────────────────────────────────────────────────────────────┐
│  MICROSERVIÇO          │  GO                                    │
├─────────────────────────────────────────────────────────────────┤
│  Leve e rápido         │  Binário único, startup < 100ms        │
├─────────────────────────────────────────────────────────────────┤
│  Escalável             │  Goroutines (milhões simultâneas)      │
├─────────────────────────────────────────────────────────────────┤
│  Confiável             │  Tipagem forte, sem runtime pesado     │
├─────────────────────────────────────────────────────────────────┤
│  Eficiente             │  Memória mínima (10-50MB por serviço)  │
├─────────────────────────────────────────────────────────────────┤
│  Portátil              │  Cross-compile, Docker nativo          │
├─────────────────────────────────────────────────────────────────┤
│  Simples               │  Código explícito, fácil manutenção    │
└─────────────────────────────────────────────────────────────────┘

Comparação com Outras Linguagens

AspectoGoJavaNode.jsPython
Startup~50ms~5s~2s~1s
Memória10-50MB200-500MB100-300MB150-400MB
ConcorrênciaNativaThreads pesadasCallbacksGIL limita
BinárioÚnicoJVM necessáriaNode runtimeInterpreter
PerformanceNativaBoa (JIT)MédiaLenta

Arquitetura de um Microserviço Go

Estrutura de Projeto Recomendada

order-service/
├── cmd/
│   └── api/
│       └── main.go              # Entry point
├── internal/
│   ├── domain/
│   │   ├── order.go             # Entidades
│   │   └── errors.go            # Erros de domínio
│   ├── application/
│   │   ├── service.go           # Lógica de negócio
│   │   └── dto.go               # Data Transfer Objects
│   ├── infrastructure/
│   │   ├── http/
│   │   │   ├── handler.go       # HTTP handlers
│   │   │   ├── router.go        # Configuração de rotas
│   │   │   └── middleware.go    # Middlewares
│   │   ├── persistence/
│   │   │   ├── postgres.go      # Implementação do repo
│   │   │   └── redis.go         # Cache
│   │   └── messaging/
│   │       └── kafka.go         # Event publisher
│   └── config/
│       └── config.go            # Configurações
├── pkg/
│   └── logger/                  # Shared packages
├── api/
│   └── proto/                   # Protocol Buffers
├── deployments/
│   ├── docker/
│   └── k8s/
├── go.mod
└── Makefile

Implementação Completa

// internal/domain/order.go
package domain

import (
	"errors"
	"time"
)

var (
	ErrInvalidAmount  = errors.New("valor do pedido inválido")
	ErrOrderNotFound  = errors.New("pedido não encontrado")
)

type Order struct {
	ID        string    `json:"id"`
	UserID    string    `json:"user_id"`
	Items     []Item    `json:"items"`
	Total     float64   `json:"total"`
	Status    Status    `json:"status"`
	CreatedAt time.Time `json:"created_at"`
}

type Item struct {
	ProductID string  `json:"product_id"`
	Quantity  int     `json:"quantity"`
	Price     float64 `json:"price"`
}

type Status string

const (
	StatusPending   Status = "PENDING"
	StatusPaid      Status = "PAID"
	StatusShipped   Status = "SHIPPED"
	StatusDelivered Status = "DELIVERED"
)

func (o *Order) CalculateTotal() {
	var total float64
	for _, item := range o.Items {
		total += item.Price * float64(item.Quantity)
	}
	o.Total = total
}

func (o *Order) Validate() error {
	if o.Total <= 0 {
		return ErrInvalidAmount
	}
	return nil
}
// internal/application/service.go
package application

import (
	"context"
	"fmt"
	"time"

	"order-service/internal/domain"
)

// Portas (interfaces) para dependências
type OrderRepository interface {
	Save(ctx context.Context, order *domain.Order) error
	GetByID(ctx context.Context, id string) (*domain.Order, error)
	Update(ctx context.Context, order *domain.Order) error
}

type PaymentService interface {
	Process(ctx context.Context, orderID string, amount float64) error
}

type EventPublisher interface {
	PublishOrderCreated(ctx context.Context, order *domain.Order) error
}

type OrderService struct {
	repo      OrderRepository
	payment   PaymentService
	publisher EventPublisher
}

func NewOrderService(
	repo OrderRepository,
	payment PaymentService,
	publisher EventPublisher,
) *OrderService {
	return &OrderService{
		repo:      repo,
		payment:   payment,
		publisher: publisher,
	}
}

func (s *OrderService) CreateOrder(ctx context.Context, userID string, items []domain.Item) (*domain.Order, error) {
	order := &domain.Order{
		ID:        generateID(),
		UserID:    userID,
		Items:     items,
		Status:    domain.StatusPending,
		CreatedAt: time.Now(),
	}

	order.CalculateTotal()
	if err := order.Validate(); err != nil {
		return nil, err
	}

	// Salvar no banco
	if err := s.repo.Save(ctx, order); err != nil {
		return nil, fmt.Errorf("falha ao salvar pedido: %w", err)
	}

	// Publicar evento assíncrono
	go func() {
		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
		defer cancel()
		s.publisher.PublishOrderCreated(ctx, order)
	}()

	return order, nil
}

func (s *OrderService) ProcessPayment(ctx context.Context, orderID string) error {
	order, err := s.repo.GetByID(ctx, orderID)
	if err != nil {
		return err
	}

	if err := s.payment.Process(ctx, orderID, order.Total); err != nil {
		return fmt.Errorf("pagamento falhou: %w", err)
	}

	order.Status = domain.StatusPaid
	return s.repo.Update(ctx, order)
}

func generateID() string {
	return fmt.Sprintf("ORD-%d", time.Now().UnixNano())
}

Padrões de Comunicação

1. Síncrono: HTTP REST

Já coberto no guia de APIs REST. Para microserviços, adicione:

Ler mais →