Skip to content

Conversation

@ch3nnn
Copy link
Contributor

@ch3nnn ch3nnn commented Apr 12, 2025

Description (what this PR does / why we need it):

  • Add Response method to Transport interface in transport/http/transport.go
  • Implement Response method in Transport struct
  • Add test for Response method in transport/http/transport_test.go
  • Implement Response method in mockTransport for testing purposes

Example:

HTTP and gRPC server code generated by Protobuf, where HTTP supports file downloads and gRPC retrieves file data.

syntax = "proto3";

package demo.v1;

import "google/api/annotations.proto";

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

service Demo {
  rpc Download(DownloadReq) returns (DownloadResp) {
    option (google.api.http) = {
      get : "api/v1/download"
    };
  }
}

message DownloadReq {
}

message DownloadResp {
  bytes data = 1;
}
func (s *Service) Download(ctx context.Context, in *v1.DownloadReq) (*v1.DownloadResp, error) {
	f := excelize.NewFile()
	index, err := f.NewSheet("Sheet2")
	if err != nil {
		return nil, err
	}

	f.SetCellValue("Sheet2", "A2", "Hello world.")
	f.SetCellValue("Sheet1", "B2", 100)
	f.SetActiveSheet(index)

	if tr, ok := transport.FromServerContext(ctx); ok {
		if tr.Kind() == transport.KindHTTP {
			h := tr.(*http.Transport)
			disposition := fmt.Sprintf("attachment; filename=%s", "demo.xlsx")
			h.ReplyHeader().Set("Content-Type", "application/octet-stream")
			h.ReplyHeader().Set("Content-Disposition", disposition)
			h.ReplyHeader().Set("Access-Control-Expose-Headers", "Content-Disposition")

                         // get response obj
			if err := f.Write(h.Response()); err != nil {
				return nil, err
			}

			return nil, nil
		}
		if tr.Kind() == transport.KindGRPC {
			buffer, err := f.WriteToBuffer()
			if err != nil {
				s.log.ErrorContext(ctx, err.Error())
				return nil, err
			}
			return &v1.DownloadResp{Data: buffer.Bytes()}, nil
		}
	}

	return nil, errors.New("transport kind error")
}

Which issue(s) this PR fixes (resolves / be part of):

Other special notes for the reviewers:

- Add Response method to Transport interface in transport/http/transport.go
- Implement Response method in Transport struct
- Add test for Response method in transport/http/transport_test.go
- Implement Response method in mockTransport for testing purposes
@dosubot dosubot bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Apr 12, 2025
@cyberxnomad
Copy link

I think this is similar to #3555 and would solve the #3611 problem as well.
I think this is useful for developing MCP (Model Context Protocol) related applications.
@shenqidebaozi, what do you think?

@dosubot dosubot bot added the LGTM label Apr 23, 2025
@tonybase tonybase merged commit 23ae7cb into go-kratos:main Apr 23, 2025
34 checks passed
qingbozhang pushed a commit to qingbozhang/kratos that referenced this pull request Sep 12, 2025
- Add ResponseTransporter interface extending Transporter with Response() method
- Add ResponseWriterFromServerContext helper function for safe access
- Maintain backward compatibility with existing Transporter implementations
- Follow Go standard library patterns (io.Reader + io.ReaderFrom)

Fixes dependency chain breaking changes from PR go-kratos#3624
qingbozhang added a commit to qingbozhang/kratos that referenced this pull request Sep 12, 2025
… interface

- Add ResponseTransporter interface extending Transporter with Response() method
- Add ResponseWriterFromServerContext helper function for safe access
- Maintain backward compatibility with existing implementations
- Resolve dependency chain breaking changes from PR go-kratos#3624
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

LGTM size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants