kratos-mapper

alecszaharia's avatarfrom alecszaharia

Generates bidirectional mapper functions between protobuf DTOs and business models for go-kratos services. Creates type-safe conversions with proper field mapping. Use when implementing service layer mappers.

⭐0stars🔀0forks📁View on GitHub🕐Updated Dec 29, 2025

When & Why to Use This Skill

The kratos-mapper skill automates the creation of type-safe bidirectional mapper functions between Protobuf DTOs and business domain models specifically for the Go-Kratos framework. It streamlines microservice development by handling complex field transformations—including timestamps, enums, and pagination metadata—ensuring architectural consistency while significantly reducing manual boilerplate code.

Use Cases

  • Converting incoming Protobuf request DTOs into internal business domain models to maintain a clean separation of concerns.
  • Transforming internal business entities into Protobuf response messages for consistent API delivery.
  • Standardizing the mapping of pagination parameters and metadata between the transport layer and service logic.
  • Handling repetitive and error-prone type conversions for specialized fields like Go time.Time to Protobuf Timestamps and custom enums.
  • Implementing entity transformers in Go-Kratos service layers to ensure type safety and nil-pointer protection during data transfer.
namekratos-mapper
descriptionGenerates bidirectional mapper functions (transformers/converters/adapters) between protobuf DTOs and business domain models for go-kratos services. Creates type-safe conversions with proper field mapping, handles timestamps, enums, optional fields, and pagination metadata transformations. Use when converting DTOs to domain models, transforming proto to biz models, mapping requests/responses, implementing type conversions, creating entity transformers, or handling DTO transformations between layers.
tags[kratos, mapper, dto, converter, transformer, proto, domain-model, type-conversion]
keywords[mapper, convert, transform, DTO, proto to domain, domain to proto, type conversion, request mapping, response mapping, transformer, converter, adapter]
version2.0.0
last_updated2026-01-12
Generate mapper functions that convert between protobuf DTOs (requests/responses) and business domain models, ensuring type safety and proper field transformations. For an entity, create mappers in `internal/service/mapper.go`:
// Request → Business Model
func {Entity}FromCreateRequest(req *pb.Create{Entity}Request) *biz.{Entity} {
	return &biz.{Entity}{
		Name: req.Name,
		// Map fields...
	}
}

// Business Model → Proto Response
func toProto{Entity}(e *biz.{Entity}) *pb.{Entity} {
	return &pb.{Entity}{
		Id:   e.ID,
		Name: e.Name,
		// Map fields...
	}
}
## Common Mapper Patterns

Request to Business Model:

func {Entity}FromCreateRequest(req *pb.Create{Entity}Request) *biz.{Entity}
func {Entity}FromUpdateRequest(req *pb.Update{Entity}Request, id uint64) *biz.{Entity}

Business Model to Proto:

func toProto{Entity}(e *biz.{Entity}) *pb.{Entity}
func toProto{Entities}(list []*biz.{Entity}) []*pb.{Entity}

List Options:

func NewList{Entities}Options(req *pb.List{Entities}Request) *biz.List{Entities}Options {
	return &biz.List{Entities}Options{
		Pagination: pagination.PaginationParams{
			Offset: req.Offset,
			Limit:  req.Limit,
		},
	}
}

Pagination Meta:

func toProtoPaginationMeta(meta *pagination.PaginationMeta) *pb.PaginationMeta {
	return &pb.PaginationMeta{
		Total:  meta.Total,
		Offset: meta.Offset,
		Limit:  meta.Limit,
	}
}
## Naming Rules

Proto → Business: {Entity}From{Operation}Request

  • Example: SymbolFromCreateRequest, ProductFromUpdateRequest

Business → Proto: toProto{Entity} or toProto{Entities}

  • Example: toProtoSymbol, toProtoSymbols

Options: NewList{Entities}Options

Helpers: toProto{Type} for common types

  • Example: toProtoPaginationMeta, toProtoTimestamp
## Common Type Conversions

IDs: uint64 ↔ uint64 (direct) Strings: string ↔ string (direct) Timestamps: time.Time ↔ *timestamppb.Timestamp

CreatedAt: timestamppb.New(e.CreatedAt)

Optional Fields: Use pointers

// Business has *string, proto has string
Email: func() string {
	if e.Email != nil {
		return *e.Email
	}
	return ""
}()

Enums: Map string to proto enum

Status: pb.Status(pb.Status_value[e.Status])
## Where to Put Mappers

Single entity: internal/service/mapper.go (all mappers) Multiple entities: internal/service/{entity}_mapper.go (per entity)

Keep mapper functions close to service handlers for easy reference.

Mapper functions are correct when: - [ ] Naming follows conventions ({Entity}From* vs toProto*) - [ ] All proto fields mapped to business model fields - [ ] Type conversions handled (timestamps, optionals, enums) - [ ] Nil checks for optional/pointer fields - [ ] List mappers use range loops - [ ] Pagination helpers created if needed - [ ] Functions are pure (no side effects)