-
Notifications
You must be signed in to change notification settings - Fork 7
Description
Is your feature request related to a problem? Please describe.
Currently, sebuf's protoc-gen-go-http only supports JSON-serialized protobuf message responses. This limitation prevents sebuf from being used for APIs that need to return binary data such as images (PNG, JPG), PDFs, or other non-JSON content types. This forces developers to either handle binary endpoints separately outside of sebuf or adopt workarounds like base64-encoding binary data in JSON, which is inefficient and doesn't follow REST standards.
Describe the solution you'd like
Extend protoc-gen-go-http to support binary response types. When a service method returns a message containing only a bytes field, the code generator should produce HTTP handlers that:
- Stream the bytes directly without JSON marshaling
- Set appropriate
Content-Typeheaders based on the endpoint's requirements - Return the raw binary data with proper HTTP headers (Content-Length, caching headers, etc.)
- Generate correct OpenAPI documentation for binary responses
Describe alternatives you've considered
- Keep binary endpoints outside sebuf - requires manual HTTP handler management and loses benefits of sebuf's validation, documentation generation, and consistency
- Base64-encode binary in JSON responses - adds 33% overhead and doesn't follow RESTful patterns for serving binary assets
- Use gRPC streaming - different protocol, doesn't solve the REST API use case
- Return binary data as a separate service - adds complexity and doesn't integrate with existing protobuf service definitions
Use Cases
- Asset/Logo APIs - Services like Alpaca Markets that need to serve company logos or asset images:
GET /v1beta1/logos/{symbol} -> returns PNG image
- Document Generation - APIs that generate and return PDFs, CSVs, or other documents on demand:
GET /api/v1/reports/{id}/download -> returns PDF document
- File Download Endpoints - APIs that serve user-generated content, certificates, or processed files:
GET /api/v1/files/{id}/content -> returns binary file
Proposed API/Interface (if applicable)
syntax = "proto3";
package alpaca.logos;
import "sebuf/http/annotations.proto";
service LogoService {
rpc GetLogo(GetLogoRequest) returns (LogoResponse) {
option (sebuf.http.response_content_type) = "image/png";
};
rpc GetDocument(GetDocumentRequest) returns (DocumentResponse) {
option (sebuf.http.response_content_type) = "application/pdf";
};
}
message GetLogoRequest {
string symbol = 1;
bool placeholder = 2;
}
message LogoResponse {
bytes image_data = 1;
}
message GetDocumentRequest {
string document_id = 1;
}
message DocumentResponse {
bytes content = 1;
}// Generated code would resemble:
func (s *logoServiceServer) GetLogo(w http.ResponseWriter, r *http.Request) error {
// ... validation and business logic ...
resp, err := s.impl.GetLogo(r.Context(), &req)
if err != nil {
return err
}
// Direct binary streaming instead of JSON marshaling
w.Header().Set("Content-Type", "image/png")
w.Header().Set("Content-Length", strconv.Itoa(len(resp.ImageData)))
w.WriteHeader(http.StatusOK)
w.Write(resp.ImageData)
return nil
}
func (s *logoServiceServer) GetDocument(w http.ResponseWriter, r *http.Request) error {
// ... validation and business logic ...
resp, err := s.impl.GetDocument(r.Context(), &req)
if err != nil {
return err
}
w.Header().Set("Content-Type", "application/pdf")
w.Header().Set("Content-Length", strconv.Itoa(len(resp.Content)))
w.WriteHeader(http.StatusOK)
w.Write(resp.Content)
return nil
}Impact on Existing Code
- This is a breaking change
- This is backwards compatible
- This requires migration steps
This feature would be fully backwards compatible - existing protobuf services would continue to work as before. The new functionality only activates when the optional response_content_type annotation is used or when a response message contains only a single bytes field.
Additional Context
- The annotation could be added to
sebuf/http/annotations.proto - The code generator needs to detect single-
bytesfield responses and treat them specially - OpenAPI generation should output
format: binaryfor these endpoints - This aligns with how other HTTP API frameworks (like Echo, Gin, standard library) handle binary responses
Are you willing to contribute this feature?
- Yes, I can implement this feature
- Yes, but I would need guidance
- No, but I can help test it
- No