Files
go-micro/internal/website/blog/6.md
T
Asim AslamandClaude 76bfeae456 Claude/update docs roadmap f zd2 j (#2880)
* docs: update all four documentation guides and mark Q2 complete

- ai-native-services: add WithMCP one-liner, standalone gateway,
  WebSocket client example, and OpenTelemetry observability section
- mcp-security: add OTel distributed tracing, WebSocket authentication
  (connection-level and per-message), DeniedReason audit field
- tool-descriptions: add manual overrides with WithEndpointDocs and
  export formats section
- agent-patterns: add LangChain/LlamaIndex SDK pattern and standalone
  gateway production pattern with Docker example
- Update roadmap: mark Q2 documentation as complete, Q2 at 100%
- Update status: reflect all recent completions, shift priorities

https://claude.ai/code/session_01GkduEhcrqcG45rdfYh8dAc

* feat: add agent demo example and blog post

Add examples/agent-demo with a multi-service project management app
(projects, tasks, team) that demonstrates AI agents interacting with
Go Micro services through MCP. Includes seed data and example prompts.

Add blog post 4 "Agents Meet Microservices: A Hands-On Demo" walking
through the example code and showing cross-service agent workflows.

https://claude.ai/code/session_01GkduEhcrqcG45rdfYh8dAc

* feat: enable multiple services in a single binary

Remove global state mutations from service and cmd option functions so
that configuring one service no longer overwrites another's settings.

Key changes:
- service/options.go: remove all DefaultXxx global writes from option
  functions; newOptions() now creates fresh Server, Client, Store, and
  Cache per service while sharing Registry, Broker, and Transport
- cmd/cmd.go: newCmd() uses local copies instead of pointers to package
  globals; Before() no longer mutates DefaultXxx vars
- cmd/options.go: remove global mutations from all option functions
- service/service.go: export ServiceImpl type for cross-package use
- service/group.go: new Group type for multi-service lifecycle
- micro.go: add Start/Stop to Service interface, expose Group and
  NewGroup convenience function
- examples/multi-service: working example with two services

https://claude.ai/code/session_01GkduEhcrqcG45rdfYh8dAc

* docs: highlight multi-service binary support

Add multi-service section to README with code example, update features
list, add to examples index, and note in status summary.

https://claude.ai/code/session_01GkduEhcrqcG45rdfYh8dAc

* feat: unify service API and clean up developer experience

- Unified service creation: micro.New("name", opts...) as canonical API
- Clean handler registration: service.Handle(handler, opts...) accepts
  server.HandlerOption args directly, no need to reach through Server()
- Unexported serviceImpl: users interact through Service interface only
- Service groups use Service interface (not concrete type)
- Fixed Stop() to properly propagate BeforeStop/AfterStop errors
- Fixed store init: error-level log instead of fatal on init failure
- Updated all examples to use consistent patterns
- Updated README, getting-started, MCP docs, and guides
- Added blog post about the DX cleanup

https://claude.ai/code/session_01GkduEhcrqcG45rdfYh8dAc

* fix: add blog post 5 to blog index

Blog post 5 (Developer Experience Cleanup) existed as a file but was
missing from the blog index page.

https://claude.ai/code/session_01GkduEhcrqcG45rdfYh8dAc

* feat: make micro new generate MCP-enabled services by default

- main.go template includes mcp.WithMCP(":3001") by default
- Handler template has agent-friendly doc comments with @example tags
- Proto template has descriptive field comments
- README includes MCP usage, Claude Code config, and tool description tips
- Makefile adds mcp-tools, mcp-test, mcp-serve targets
- go.mod updated to Go 1.22
- Added --no-mcp flag to opt out of MCP integration
- Post-create output shows MCP endpoint URLs

https://claude.ai/code/session_01GkduEhcrqcG45rdfYh8dAc

* docs: add MCP migration guide and troubleshooting guide

- Migration guide: 3 approaches to add MCP to existing services
  (WithMCP one-liner, standalone gateway, CLI)
- Troubleshooting guide: common issues with agents, WebSocket,
  Claude Code, auth, rate limiting, and performance

https://claude.ai/code/session_01GkduEhcrqcG45rdfYh8dAc

* refactor: rename model/ package to ai/ for AI model providers

The model/ package name conflicted with the conventional use of "model"
for data models. Renamed to ai/ which better describes the package's
purpose (AI provider abstraction for Anthropic, OpenAI, etc.) and frees
up model/ for future data model layer use.

- Rename model/ → ai/ with package name change
- Update all Go imports from go-micro.dev/v5/model to go-micro.dev/v5/ai
- Update cmd/micro/server/server.go references (model.X → ai.X)
- Update all documentation and roadmap references
- All tests pass, CLI builds successfully

https://claude.ai/code/session_01GkduEhcrqcG45rdfYh8dAc

* feat: add model package for typed data access with CRUD and queries

New model/ package provides a typed data model layer using Go generics.
Supports structured CRUD operations, WHERE filters, ordering, pagination,
and automatic schema creation from struct tags.

Three backends:
- memory: in-memory for development and testing
- sqlite: embedded SQL for dev and single-node production
- postgres: full PostgreSQL for production deployments

Key features:
- Generic Model[T] with Create/Read/Update/Delete/List/Count
- Query builder: Where(), WhereOp(), OrderAsc/Desc(), Limit(), Offset()
- Struct tags: model:"key" for primary key, model:"index" for indexes
- Auto table creation from struct schema
- 19 tests passing across memory and sqlite backends

https://claude.ai/code/session_01GkduEhcrqcG45rdfYh8dAc

* feat: add model code generation to protoc-gen-micro

Extend the micro plugin to generate model structs from proto messages
annotated with // @model. Generated alongside client/server code in
the same .pb.micro.go file.

For a proto message like:
  // @model
  message User { string id = 1; string name = 2; }

Generates:
- UserModel struct with model:"key" and json tags
- NewUserModel(db) factory returning *model.Model[UserModel]
- UserModelFromProto(*User) *UserModel converter
- (*UserModel).ToProto() *User converter

Supports @model(table=custom_table, key=custom_field) options.
Adds GetComments() to generator for plugin comment inspection.

https://claude.ai/code/session_01GkduEhcrqcG45rdfYh8dAc

* feat: add Model() to Service interface for Client/Server/Model trifecta

Every service now exposes Client(), Server(), and Model() — call services,
handle requests, and save/query data from the same interface. Includes
README docs, blog post, and a full model guide on the docs site.

https://claude.ai/code/session_01GkduEhcrqcG45rdfYh8dAc

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-04 13:13:34 +00:00

5.0 KiB

layout, title, permalink, description
layout title permalink description
blog The Model Package: Client, Server, and Now Data /blog/6 Go Micro now has a typed data model layer — define structs, get CRUD and queries, swap backends. Every service gets Client, Server, and Model.

The Model Package: Client, Server, and Now Data

March 4, 2026 — By the Go Micro Team

Go Micro has always given you service.Client() to call other services and service.Server() to handle requests. But most services also need to save and query data. Until now, that meant either using the low-level store package (key-value only) or wiring up your own database layer.

Today we're shipping the model package — a typed data model layer that completes the service trifecta: Client, Server, Model.

The Problem

The existing store package is great for simple key-value storage, but real services need more. You need to filter by fields, paginate results, count records, and use different databases in dev vs production. Most teams end up writing their own data layer or pulling in an ORM that has nothing to do with Go Micro.

We wanted something that feels native to the framework. Define a Go struct, tag a key, and get type-safe CRUD and queries — with the same pluggable backend pattern Go Micro uses everywhere.

Define a Struct, Get a Database

type User struct {
    ID    string `json:"id" model:"key"`
    Name  string `json:"name"`
    Email string `json:"email" model:"index"`
    Age   int    `json:"age"`
}

The model:"key" tag marks your primary key. The model:"index" tag creates an index for faster queries. Column names come from json tags (or lowercased field names if no tag).

Create a model and use it:

users := model.New[User](service.Model())

// Create
users.Create(ctx, &User{ID: "1", Name: "Alice", Email: "alice@example.com", Age: 30})

// Read
user, err := users.Read(ctx, "1")

// Update
user.Name = "Alice Smith"
users.Update(ctx, user)

// Delete
users.Delete(ctx, "1")

No migrations. No connection setup. No configuration files. The schema is derived from your struct at startup.

Queries That Feel Like Go

List and count with composable query options:

// Simple equality filter
active, _ := users.List(ctx, model.Where("email", "alice@example.com"))

// Operators, ordering, pagination
page, _ := users.List(ctx,
    model.WhereOp("age", ">=", 18),
    model.OrderDesc("name"),
    model.Limit(10),
    model.Offset(20),
)

// Count records
total, _ := users.Count(ctx, model.Where("age", 30))

Filters support =, !=, <, >, <=, >=, and LIKE. Everything composes — add as many query options as you need.

Three Backends, One Interface

The model layer follows Go Micro's pluggable pattern. Same code, different backends:

Memory — the default. Zero config, great for development and testing:

service := micro.New("users")
users := model.New[User](service.Model()) // in-memory by default

SQLite — single-file database for local development or single-node production:

db, _ := sqlite.New(model.WithDSN("file:app.db"))
service := micro.New("users", micro.Model(db))

Postgres — production-grade with connection pooling:

db, _ := postgres.New(model.WithDSN("postgres://localhost/myapp"))
service := micro.New("users", micro.Model(db))

Start with memory in dev, switch to SQLite or Postgres for production. Your application code doesn't change.

The Complete Service Interface

The Service interface now has three core accessors:

type Service interface {
    Client() client.Client    // Call other services
    Server() server.Server    // Handle incoming requests
    Model()  model.Database   // Save and query data
    // ...
}

This means a typical service has everything it needs in one place:

func main() {
    service := micro.New("users", micro.Address(":9001"))

    // Data layer
    users := model.New[User](service.Model())

    // Handler with data access
    service.Handle(&UserService{users: users})

    // Run
    service.Run()
}

Call services with service.Client(). Handle requests with service.Server(). Save data with service.Model(). That's the complete picture.

Multiple Models, One Database

You can create multiple typed models from the same database connection:

db := service.Model()

users    := model.New[User](db)
posts    := model.New[Post](db)
comments := model.New[Comment](db)

Each model gets its own table (derived from the struct name). They share the database connection.

What's Next

The model package is production-ready with memory, SQLite, and Postgres backends. Coming soon:

  • Relationships — define foreign keys between models
  • Migrations — track and apply schema changes
  • Protobuf codegenprotoc-gen-micro generates model code from proto definitions

See the model documentation for the full API reference, or browse the model package source to see the implementation.