Skip to content

Automatic Type-Safe Inter-Service Calls via Interface Definition #2280

@aryanmehrotra

Description

@aryanmehrotra

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    triageThe issue needs triaging.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions