Kratos provides a unified encoding system that supports multiple formats including JSON, XML, YAML, Protobuf, and form data. The system is extensible and automatically selects the appropriate codec based on content type.
Codec Interface
encoding/encoding.go:10-19
type Codec interface {
// Marshal returns the wire format of v
Marshal ( v any ) ([] byte , error )
// Unmarshal parses the wire format into v
Unmarshal ( data [] byte , v any ) error
// Name returns the name of the Codec implementation
Name () string
}
JSON
JSON encoding with Protobuf support:
encoding/json/json.go:27-69
import " github.com/go-kratos/kratos/v2/encoding/json "
type User struct {
ID int64 `json:"id"`
Name string `json:"name"`
}
user := & User { ID : 1 , Name : "John" }
// Marshal
data , err := json . Marshal ( user )
// {"id":1,"name":"John"}
// Unmarshal
var decoded User
err = json . Unmarshal ( data , & decoded )
Content-Type : application/json
JSON codec automatically handles both regular structs and Protobuf messages.
XML
XML encoding:
import " github.com/go-kratos/kratos/v2/encoding/xml "
type User struct {
XMLName xml . Name `xml:"user"`
ID int64 `xml:"id"`
Name string `xml:"name"`
}
user := & User { ID : 1 , Name : "John" }
// Marshal
data , err := xml . Marshal ( user )
// <user><id>1</id><name>John</name></user>
// Unmarshal
var decoded User
err = xml . Unmarshal ( data , & decoded )
Content-Type : application/xml, text/xml
YAML
YAML encoding:
import " github.com/go-kratos/kratos/v2/encoding/yaml "
type Config struct {
Server struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
} `yaml:"server"`
}
config := & Config {}
config . Server . Host = "localhost"
config . Server . Port = 8000
// Marshal
data , err := yaml . Marshal ( config )
// server:
// host: localhost
// port: 8000
// Unmarshal
var decoded Config
err = yaml . Unmarshal ( data , & decoded )
Content-Type : application/yaml, application/x-yaml
Protobuf
Binary Protobuf encoding:
import " github.com/go-kratos/kratos/v2/encoding/proto "
// Requires Protobuf message
msg := & pb . User { Id : 1 , Name : "John" }
// Marshal
data , err := proto . Marshal ( msg )
// Unmarshal
var decoded pb . User
err = proto . Unmarshal ( data , & decoded )
Content-Type : application/protobuf, application/x-protobuf
URL-encoded form data:
encoding/form/form.go:40-88
import " github.com/go-kratos/kratos/v2/encoding/form "
type LoginRequest struct {
Username string `json:"username"`
Password string `json:"password"`
Remember bool `json:"remember"`
}
req := & LoginRequest {
Username : "admin" ,
Password : "secret" ,
Remember : true ,
}
// Marshal
data , err := form . Marshal ( req )
// username=admin&password=secret&remember=true
// Unmarshal
var decoded LoginRequest
err = form . Unmarshal ( data , & decoded )
Content-Type : application/x-www-form-urlencoded
The form codec uses JSON struct tags by default. This can be changed by building with -ldflags="-X github.com/go-kratos/kratos/v2/encoding/form.tagName=form"
Codec Registry
Register Custom Codec
encoding/encoding.go:23-34
import " github.com/go-kratos/kratos/v2/encoding "
type MyCodec struct {}
func ( c MyCodec ) Marshal ( v any ) ([] byte , error ) {
// Custom marshaling logic
return nil , nil
}
func ( c MyCodec ) Unmarshal ( data [] byte , v any ) error {
// Custom unmarshaling logic
return nil
}
func ( c MyCodec ) Name () string {
return "mycustom"
}
// Register codec
encoding . RegisterCodec ( MyCodec {})
Get Registered Codec
encoding/encoding.go:40-42
import " github.com/go-kratos/kratos/v2/encoding "
// Get codec by name
codec := encoding . GetCodec ( "json" )
if codec != nil {
data , err := codec . Marshal ( value )
}
Automatic Codec Selection
Kratos automatically selects the codec based on Content-Type:
HTTP Server
func handleRequest ( ctx http . Context ) error {
var req LoginRequest
// Automatically decodes based on Content-Type header
if err := ctx . Bind ( & req ); err != nil {
return err
}
// Process request...
// Automatically encodes based on Accept header
return ctx . Result ( 200 , response )
}
Content-Type Mapping :
application/json → JSON codec
application/xml → XML codec
application/yaml → YAML codec
application/protobuf → Protobuf codec
application/x-www-form-urlencoded → Form codec
HTTP Client
import " github.com/go-kratos/kratos/v2/transport/http "
client , _ := http . NewClient (
ctx ,
http . WithEndpoint ( "127.0.0.1:8000" ),
)
var reply Response
err := client . Invoke (
ctx ,
"POST" ,
"/api/login" ,
& LoginRequest { Username : "admin" },
& reply ,
http . ContentType ( "application/json" ), // Specify content type
)
Custom Encoding/Decoding
HTTP Request Encoder
func customEncoder ( ctx context . Context , contentType string , in interface {}) ([] byte , error ) {
// Custom encoding logic
codec := encoding . GetCodec ( "json" )
return codec . Marshal ( in )
}
client , err := http . NewClient (
ctx ,
http . WithRequestEncoder ( customEncoder ),
)
HTTP Response Decoder
func customDecoder ( ctx context . Context , res * http . Response , out interface {}) error {
defer res . Body . Close ()
data , err := io . ReadAll ( res . Body )
if err != nil {
return err
}
// Get codec from response Content-Type
codec := encoding . GetCodec ( httputil . ContentSubtype ( res . Header . Get ( "Content-Type" )))
if codec == nil {
codec = encoding . GetCodec ( "json" )
}
return codec . Unmarshal ( data , out )
}
client , err := http . NewClient (
ctx ,
http . WithResponseDecoder ( customDecoder ),
)
Protobuf Integration
All codecs have special handling for Protobuf messages:
JSON with Protobuf
encoding/json/json.go:34-43
import pb " your-project/api/user/v1 "
msg := & pb . User { Id : 1 , Name : "John" }
// Automatically uses protojson
data , err := json . Marshal ( msg )
// Uses MarshalOptions for Protobuf-friendly JSON
var decoded pb . User
err = json . Unmarshal ( data , & decoded )
// Uses UnmarshalOptions
JSON Marshal Options :
MarshalOptions = protojson . MarshalOptions {
EmitUnpopulated : true , // Include fields with zero values
}
JSON Unmarshal Options :
UnmarshalOptions = protojson . UnmarshalOptions {
DiscardUnknown : true , // Ignore unknown fields
}
encoding/form/form.go:43-47
import pb " your-project/api/user/v1 "
msg := & pb . LoginRequest {
Username : "admin" ,
Password : "secret" ,
}
// Automatically handles Protobuf messages
data , err := form . Marshal ( msg )
var decoded pb . LoginRequest
err = form . Unmarshal ( data , & decoded )
Best Practices
Let Kratos automatically select the codec based on Content-Type rather than manually choosing.
Design APIs to accept multiple content types for flexibility (JSON, XML, etc.).
Always add JSON tags to structs even if using other formats - they’re used by form codec.
Ensure clients send the correct Content-Type header to get proper encoding/decoding.
Use Protobuf for internal service communication for better performance.
Use JSON for public APIs for better compatibility and debugging.
Format Size Speed Human Readable Schema Use Case JSON Medium Fast Yes Optional Public APIs, Web Protobuf Small Fastest No Required Internal services XML Large Slow Yes Optional Legacy systems YAML Medium Medium Yes No Configuration Form Medium Fast Yes No HTML forms
HTTP Transport HTTP encoding/decoding
gRPC Transport Protobuf encoding
Config Configuration file formats
Errors Error response encoding