Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/go-kratos/kratos/llms.txt

Use this file to discover all available pages before exploring further.

Kratos uses Protocol Buffers to define service APIs. This provides strong typing, automatic code generation, and support for both gRPC and HTTP protocols.

Basic API Definition

1
Create a Protobuf File
2
Create your API definition in the api/ directory:
3
syntax = "proto3";

package helloworld.v1;

option go_package = "helloworld/api/helloworld/v1;v1";

import "google/api/annotations.proto";

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {
    option (google.api.http) = {
      get: "/helloworld/{name}"
    };
  }
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}
4
Add HTTP Annotations
5
Kratos supports HTTP bindings through Google API annotations:
6
import "google/api/annotations.proto";

service UserService {
  // GET request
  rpc GetUser (GetUserRequest) returns (User) {
    option (google.api.http) = {
      get: "/v1/users/{id}"
    };
  }
  
  // POST request with body
  rpc CreateUser (CreateUserRequest) returns (User) {
    option (google.api.http) = {
      post: "/v1/users"
      body: "*"
    };
  }
  
  // PUT request
  rpc UpdateUser (UpdateUserRequest) returns (User) {
    option (google.api.http) = {
      put: "/v1/users/{id}"
      body: "*"
    };
  }
  
  // DELETE request
  rpc DeleteUser (DeleteUserRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/users/{id}"
    };
  }
}
7
Define Request and Response Messages
8
Create clear, well-structured messages:
9
message GetUserRequest {
  string id = 1;
}

message CreateUserRequest {
  string name = 1;
  string email = 2;
  int32 age = 3;
}

message UpdateUserRequest {
  string id = 1;
  string name = 2;
  string email = 3;
  int32 age = 4;
}

message DeleteUserRequest {
  string id = 1;
}

message User {
  string id = 1;
  string name = 2;
  string email = 3;
  int32 age = 4;
  int64 created_at = 5;
  int64 updated_at = 6;
}

Advanced HTTP Bindings

Path Parameters

Capture variables from the URL path:
rpc GetArticle (GetArticleRequest) returns (Article) {
  option (google.api.http) = {
    get: "/v1/authors/{author_id}/articles/{article_id}"
  };
}

message GetArticleRequest {
  string author_id = 1;
  string article_id = 2;
}

Query Parameters

All fields not in the path become query parameters:
rpc ListUsers (ListUsersRequest) returns (ListUsersResponse) {
  option (google.api.http) = {
    get: "/v1/users"
  };
}

message ListUsersRequest {
  int32 page = 1;      // ?page=1
  int32 page_size = 2; // &page_size=20
  string filter = 3;   // &filter=active
}

Request Body

Specify which fields should be in the request body:
// Entire request as body
rpc CreatePost (CreatePostRequest) returns (Post) {
  option (google.api.http) = {
    post: "/v1/posts"
    body: "*"
  };
}

// Specific field as body
rpc UpdatePost (UpdatePostRequest) returns (Post) {
  option (google.api.http) = {
    patch: "/v1/posts/{id}"
    body: "post"
  };
}

message UpdatePostRequest {
  string id = 1;
  Post post = 2;
}

Multiple HTTP Bindings

Support multiple HTTP endpoints for one RPC method:
rpc Search (SearchRequest) returns (SearchResponse) {
  option (google.api.http) = {
    get: "/v1/search"
    additional_bindings {
      post: "/v1/search"
      body: "*"
    }
  };
}

Error Definitions

Define custom errors using enums with Kratos error extensions:
api/helloworld/v1/errors.proto
syntax = "proto3";

package helloworld.v1;

option go_package = "helloworld/api/helloworld/v1;v1";

import "errors/errors.proto";

enum ErrorReason {
  option (errors.default_code) = 500;
  
  USER_NOT_FOUND = 0 [(errors.code) = 404];
  USER_ALREADY_EXISTS = 1 [(errors.code) = 409];
  INVALID_ARGUMENT = 2 [(errors.code) = 400];
  UNAUTHORIZED = 3 [(errors.code) = 401];
  PERMISSION_DENIED = 4 [(errors.code) = 403];
}

Validation Rules

Add validation rules using protoc-gen-validate:
import "validate/validate.proto";

message CreateUserRequest {
  string name = 1 [(validate.rules).string = {
    min_len: 2
    max_len: 50
  }];
  
  string email = 2 [(validate.rules).string.email = true];
  
  int32 age = 3 [(validate.rules).int32 = {
    gte: 0
    lte: 150
  }];
  
  string password = 4 [(validate.rules).string = {
    min_len: 8
    pattern: "^[a-zA-Z0-9@$!%*?&]+$"
  }];
}

Metadata Service

Kratos provides a built-in metadata service for API introspection:
api/metadata/metadata.proto
syntax = "proto3";

package kratos.api;

import "google/protobuf/descriptor.proto";
import "google/api/annotations.proto";

service Metadata {
  rpc ListServices (ListServicesRequest) returns (ListServicesReply) {
    option (google.api.http) = {
      get: "/services"
    };
  }
  
  rpc GetServiceDesc (GetServiceDescRequest) returns (GetServiceDescReply) {
    option (google.api.http) = {
      get: "/services/{name}"
    };
  }
}

Best Practices

Versioning

Always version your APIs (v1, v2) to allow backward compatibility

Naming

Use clear, consistent naming: GetUser, ListUsers, CreateUser, UpdateUser, DeleteUser

RESTful URLs

Follow REST conventions: /v1/users/{id} not /v1/get_user

Error Handling

Define specific error codes for each failure case

Code Generation

After defining your APIs, generate the code:
# Generate all proto files
go generate ./...

# Or use the Makefile
make api
This generates:
  • .pb.go files (protobuf messages)
  • _http.pb.go files (HTTP bindings)
  • _grpc.pb.go files (gRPC service definitions)
  • _errors.pb.go files (error definitions)

Next Steps

Code Generation

Learn about protoc plugins and code generation

Service Implementation

Implement your service logic