Automatic Type-Safe Inter-Service Calls via Interface Definition
Is your feature request related to a problem? Please describe.
Currently, in GoFr, when building microservices, developers have to manually handle inter-service communication by managing request and response, setting headers (e.g., Auth, Tracing), handling errors, and retries. This leads to repetitive boilerplate code, risks of inconsistencies, and increases development time, especially when scaling to many services.
Describe the solution you'd like
I propose a system where the user only defines a typed service interface with request and response contracts, and GoFr automatically provides a concrete implementation that handles:
- HTTP calls to the appropriate service
- Serialization and deserialization of request/response payloads
- Header injection (Auth tokens, tracing)
- Error handling, retries, and timeouts
Example usage:
type UserService interface {
GetUser(ctx context.Context, req GetUserRequest) (GetUserResponse, error)
}
type GetUserRequest struct {
UserID string `json:"user_id", qParam`
}
// similarly handle path param headers etc
type GetUserResponse struct {
Name string `json:"name"`
Email string `json:"email"`
}
// User calls the service like this:
userSvc := ctx.GetHttpService[UserService]()
resp, err := userSvc.GetUser(ctx, GetUserRequest{UserID: "abc123"})
// the above way might not be possible but we can look for something which can make it this easy
This allows developers to focus purely on business logic and removes the burden of boilerplate code.
Describe alternatives you've considered
-
Manual client implementations: Every service defines its own HTTP/gRPC client and handles serialization, headers, etc., manually.
- ❌ High boilerplate, error-prone, difficult to maintain at scale.
-
Code generation tools (OpenAPI, Protobuf): Requires separate codegen step and configuration.
- ⚠️ Adds complexity and slows down the developer iteration loop.
Additional context
✅ Pros:
- Strong type safety enforced by Go compiler
- Zero boilerplate for developers
- Automatic handling of headers, retries, timeouts
- Easier onboarding of new developers
- Consistent inter-service communication across projects
⚠️ Cons:
- May introduce runtime overhead if implemented with dynamic proxies
⚡ Extensibility Ideas:
- Support pluggable transports (HTTP, gRPC, messaging)
- Configurable serialization format (JSON, Protobuf, Msgpack)
- Declarative retry/circuit breaker policies
- Support interceptors/middleware (for logging, metrics, tracing)
- Enable service discovery via config or registry
- Allow fallback methods or mocks for testing
I’d also love to see this implemented. Since GoFr wraps responses within a data field, marshalling and unmarshalling often lead to errors (something I’ve personally encountered quite a few times). It would be great if GoFr could handle this behavior in-built.