Documentation
¶
Index ¶
- Constants
- func Map[To, From any](ctx context.Context, from From) (_ To, returnErr error)
- func MustMap[To, From any](ctx context.Context, from From) To
- func Register[From, To any](mapTo mapFunc[From, To], mapFrom mapFunc[To, From]) func()
- type ErrMustMap
- type MK
- type MP
- type Mapper
- type Mapping
- type P
Examples ¶
Constants ¶
const ErrNoMapping errorkit.Error = "[dtokit] missing mapping"
Variables ¶
This section is empty.
Functions ¶
func Map ¶
Example ¶
package main import ( "context" "strconv" "go.llib.dev/frameless/pkg/dtokit" ) func main() { var _ = dtokit.Register[Ent, EntDTO]( // only once at the global level EntMapping{}.ToDTO, EntMapping{}.ToEnt, ) var ( ctx = context.Background() ent = Ent{V: 42, N: 12} ) dto, err := dtokit.Map[EntDTO](ctx, ent) if err != nil { panic(err) } gotEnt, err := dtokit.Map[Ent](ctx, dto) if err != nil { panic(err) } _ = gotEnt == ent // true } type Ent struct { V int N int } type EntDTO struct { V string `json:"v"` N int `json:"n"` } type EntMapping struct{} func (EntMapping) ToDTO(ctx context.Context, ent Ent) (EntDTO, error) { return EntDTO{V: strconv.Itoa(ent.V), N: ent.N}, nil } func (EntMapping) ToEnt(ctx context.Context, dto EntDTO) (Ent, error) { v, err := strconv.Atoi(dto.V) if err != nil { return Ent{}, err } return Ent{V: v, N: dto.N}, nil }
Example (SliceSyntaxSugar) ¶
package main import ( "context" "strconv" "go.llib.dev/frameless/pkg/dtokit" ) func main() { var _ = dtokit.Register[Ent, EntDTO]( // only once at the global level EntMapping{}.ToDTO, EntMapping{}.ToEnt, ) var ( ctx = context.Background() ents = []Ent{{V: 42, N: 12}} ) // all individual value will be mapped res, err := dtokit.Map[[]EntDTO](ctx, ents) if err != nil { panic(err) } _ = res // []EntDTO{V: "42", N: 12} } type Ent struct { V int N int } type EntDTO struct { V string `json:"v"` N int `json:"n"` } type EntMapping struct{} func (EntMapping) ToDTO(ctx context.Context, ent Ent) (EntDTO, error) { return EntDTO{V: strconv.Itoa(ent.V), N: ent.N}, nil } func (EntMapping) ToEnt(ctx context.Context, dto EntDTO) (Ent, error) { v, err := strconv.Atoi(dto.V) if err != nil { return Ent{}, err } return Ent{V: v, N: dto.N}, nil }
func Register ¶
func Register[From, To any](mapTo mapFunc[From, To], mapFrom mapFunc[To, From]) func()
Register function facilitates the registration of a mapping between two types. Optionally, if you don't intend to support bidirectional mapping, you can pass nil for the mapFrom argument. It's important to consider that supporting bidirectional mapping between an entity type and a DTO type often leads to the creation of non-partial DTO structures, enhancing their usability on the client side.
Example ¶
package main import ( "context" "encoding/json" "strconv" "go.llib.dev/frameless/pkg/dtokit" ) func main() { // JSONMapping will contain mapping from entities to JSON DTO structures. // registering Ent <---> EntDTO mapping _ = dtokit.Register[Ent, EntDTO]( EntMapping{}.ToDTO, EntMapping{}.ToEnt, ) // registering NestedEnt <---> NestedEntDTO mapping, which includes the mapping of the nested entities _ = dtokit.Register[NestedEnt, NestedEntDTO]( NestedEntMapping{}.ToDTO, NestedEntMapping{}.ToEnt, ) var v = NestedEnt{ ID: "42", Ent: Ent{ V: 42, }, } ctx := context.Background() dto, err := dtokit.Map[NestedEntDTO](ctx, v) if err != nil { // handle err return } _ = dto // data mapped into a DTO and now ready for marshalling /* NestedEntDTO{ ID: "42", Ent: EntDTO{ V: "42", }, } */ data, err := json.Marshal(dto) if err != nil { // handle error return } _ = data /* { "id": "42", "ent": { "v": "42" } } */ } type Ent struct { V int N int } type EntDTO struct { V string `json:"v"` N int `json:"n"` } type EntMapping struct{} func (EntMapping) ToDTO(ctx context.Context, ent Ent) (EntDTO, error) { return EntDTO{V: strconv.Itoa(ent.V), N: ent.N}, nil } func (EntMapping) ToEnt(ctx context.Context, dto EntDTO) (Ent, error) { v, err := strconv.Atoi(dto.V) if err != nil { return Ent{}, err } return Ent{V: v, N: dto.N}, nil } type NestedEnt struct { ID string Ent Ent } type NestedEntDTO struct { ID string `json:"id"` Ent EntDTO `json:"ent"` } type NestedEntMapping struct{} func (NestedEntMapping) ToEnt(ctx context.Context, dto NestedEntDTO) (NestedEnt, error) { return NestedEnt{ ID: dto.ID, Ent: dtokit.MustMap[Ent](ctx, dto.Ent), }, nil } func (NestedEntMapping) ToDTO(ctx context.Context, ent NestedEnt) (NestedEntDTO, error) { return NestedEntDTO{ ID: ent.ID, Ent: dtokit.MustMap[EntDTO](ctx, ent.Ent), }, nil }
Example (PartialDTOMappingSupport) ¶
package main import ( "context" "go.llib.dev/frameless/pkg/dtokit" ) func main() { // When we only need an Entity to EntityPartialDTO mapping. dtokit.Register[Ent, EntPartialDTO](EntToEntPartialDTO, nil)() var ( ctx = context.Background() v = Ent{V: 42, N: 12} ) partialDTO, err := dtokit.Map[EntPartialDTO](ctx, v) _, _ = partialDTO, err } type Ent struct { V int N int } type EntPartialDTO struct { N int `json:"n"` } func EntToEntPartialDTO(ctx context.Context, ent Ent) (EntPartialDTO, error) { return EntPartialDTO{N: ent.N}, nil }
Types ¶
type ErrMustMap ¶
type ErrMustMap struct{ Err error }
func (ErrMustMap) Error ¶
func (err ErrMustMap) Error() string
type Mapper ¶ added in v0.230.0
type Mapper[Entity any] interface { // NewDTO should return back a new(DTO) value. // It is ideal to use with Unmarshal functions such as json.Unmarshal. // // The main reason for hiding the information of DTO type, // is because where you use a Mapper[Entity] interface // is often not aware what will be the DTO type, // especially with reusable generic code, // and most serializer implementation fine with accepting an "any" argument type. NewDTO() (dtoPointer any) // MapToEnt expected to map a *DTO value to an Entity value. MapToEnt(ctx context.Context, dtoPointer any) (Entity, error) // MapToDTO expected to map an Entity value to a DTO value. MapToDTO(ctx context.Context, ent Entity) (DTO any, _ error) }
Mapper is a generic interface used for representing a Entity-DTO mapping relationship. Its primary function is to allow Resource to list various mappings, each with its own DTO type, for different MIMEType values. This means we can use different DTO types within the same restful Resource handler based on different content types, making it more flexible and adaptable to support different Serialization formats.
Implemented by Mapping[Entity, DTO]
type Mapping ¶ added in v0.230.0
type Mapping[Entity, DTO any] struct { // ToEnt is an optional function to describe how to map a DTO into an Entity. // // default: dtokit.Map[Entity, DTO](...) ToEnt func(ctx context.Context, dto DTO) (Entity, error) // ToDTO is an optional function to describe how to map an Entity into a DTO. // // default: dtokit.Map[DTO, Entity](...) ToDTO func(ctx context.Context, ent Entity) (DTO, error) }
Mapping is a type safe implementation for the generic Mapping interface. When using the frameless/pkg/dtos package, all you need to provide is the type arguments; nothing else is required.