Repository: googleapis/gapic-generator-go
Pull request #1594 (2024-12-09 17:32:21)

fix: have a helper that returns a http Response as well
When a rpc returns an httpBody, see
https://pkg.go.dev/google.golang.org/genproto/googleapis/api/httpbody#HttpBody, we need to return a response from the helper so we can examine the headers.


Patch:
diff --git a/internal/gengapic/gengapic.go b/internal/gengapic/gengapic.go
index 8a95cc6..1475a70 100644
--- a/internal/gengapic/gengapic.go
+++ b/internal/gengapic/gengapic.go
@@ -268,22 +268,28 @@ func (g *generator) genAndCommitHelpers(scopes []string) error {
 		g.imports[pbinfo.ImportSpec{Path: "google.golang.org/api/googleapi"}] = true
 		g.imports[pbinfo.ImportSpec{Path: "github.com/googleapis/gax-go/v2/internallog"}] = true
 
-		p("func executeHTTPRequest(ctx context.Context, client *http.Client, req *http.Request, logger *slog.Logger,	body []byte, rpc string) ([]byte, error) {")
+		p("func executeHTTPRequestWithResponse(ctx context.Context, client *http.Client, req *http.Request, logger *slog.Logger, body []byte, rpc string) ([]byte, *http.Response, error) {")
 		p(`  logger.DebugContext(ctx, "api request", "serviceName", serviceName, "rpcName", rpc, "request", internallog.HTTPRequest(req, body))`)
 		p("  resp, err := client.Do(req)")
 		p("  if err != nil{")
-		p("    return nil, err")
+		p("    return nil, nil, err")
 		p("  }")
 		p("  defer resp.Body.Close()")
 		p("  buf, err := io.ReadAll(resp.Body)")
 		p("  if err != nil {")
-		p("    return nil, err")
+		p("    return nil, nil, err")
 		p("  }")
 		p(`  logger.DebugContext(ctx, "api response", "serviceName", serviceName, "rpcName", rpc, "response", internallog.HTTPResponse(resp, buf))`)
 		p("  if err = googleapi.CheckResponse(resp); err != nil {")
-		p("    return nil, err")
+		p("    return nil, nil, err")
 		p("  }")
-		p("  return buf, nil")
+		p("  return buf, resp, nil")
+		p("}")
+		p("")
+
+		p("func executeHTTPRequest(ctx context.Context, client *http.Client, req *http.Request, logger *slog.Logger, body []byte, rpc string) ([]byte, error) {")
+		p("  buf, _, err := executeHTTPRequestWithResponse(ctx, client, req, logger, body, rpc)")
+		p("  return buf, err")
 		p("}")
 		p("")
 
diff --git a/internal/gengapic/genrest.go b/internal/gengapic/genrest.go
index 5230925..b4efd7d 100644
--- a/internal/gengapic/genrest.go
+++ b/internal/gengapic/genrest.go
@@ -1135,7 +1135,11 @@ func (g *generator) unaryRESTCall(servName string, m *descriptorpb.MethodDescrip
 	p("  httpReq = httpReq.WithContext(ctx)")
 	p("  httpReq.Header = headers")
 	p("")
-	p("  buf, err := executeHTTPRequest(ctx, c.httpClient, httpReq, c.logger, %s, %q)", logBody, m.GetName())
+	if isHTTPBodyMessage {
+		p("  buf, httpRsp, err := executeHTTPRequestWithResponse(ctx, c.httpClient, httpReq, c.logger, %s, %q)", logBody, m.GetName())
+	} else {
+		p("  buf, err := executeHTTPRequest(ctx, c.httpClient, httpReq, c.logger, %s, %q)", logBody, m.GetName())
+	}
 	p("  if err != nil{")
 	p("   return err")
 	p("  }")


Test patch:
diff --git a/internal/gengapic/testdata/helpers_default_scope.want b/internal/gengapic/testdata/helpers_default_scope.want
index 9fdce53..1e64a4e 100644
--- a/internal/gengapic/testdata/helpers_default_scope.want
+++ b/internal/gengapic/testdata/helpers_default_scope.want
@@ -21,22 +21,27 @@ func DefaultAuthScopes() []string {
 	}
 }
 
-func executeHTTPRequest(ctx context.Context, client *http.Client, req *http.Request, logger *slog.Logger,	body []byte, rpc string) ([]byte, error) {
+func executeHTTPRequestWithResponse(ctx context.Context, client *http.Client, req *http.Request, logger *slog.Logger, body []byte, rpc string) ([]byte, *http.Response, error) {
 	logger.DebugContext(ctx, "api request", "serviceName", serviceName, "rpcName", rpc, "request", internallog.HTTPRequest(req, body))
 	resp, err := client.Do(req)
 	if err != nil{
-		return nil, err
+		return nil, nil, err
 	}
 	defer resp.Body.Close()
 	buf, err := io.ReadAll(resp.Body)
 	if err != nil {
-		return nil, err
+		return nil, nil, err
 	}
 	logger.DebugContext(ctx, "api response", "serviceName", serviceName, "rpcName", rpc, "response", internallog.HTTPResponse(resp, buf))
 	if err = googleapi.CheckResponse(resp); err != nil {
-		return nil, err
+		return nil, nil, err
 	}
-	return buf, nil
+	return buf, resp, nil
+}
+
+func executeHTTPRequest(ctx context.Context, client *http.Client, req *http.Request, logger *slog.Logger, body []byte, rpc string) ([]byte, error) {
+	buf, _, err := executeHTTPRequestWithResponse(ctx, client, req, logger, body, rpc)
+	return buf, err
 }
 
 func executeStreamingHTTPRequest(ctx context.Context, client *http.Client, req *http.Request, logger *slog.Logger, body []byte, rpc string) (*http.Response, error) {
diff --git a/internal/gengapic/testdata/helpers_multiple_scopes.want b/internal/gengapic/testdata/helpers_multiple_scopes.want
index 2cf2254..b8fa232 100644
--- a/internal/gengapic/testdata/helpers_multiple_scopes.want
+++ b/internal/gengapic/testdata/helpers_multiple_scopes.want
@@ -23,22 +23,27 @@ func DefaultAuthScopes() []string {
 	}
 }
 
-func executeHTTPRequest(ctx context.Context, client *http.Client, req *http.Request, logger *slog.Logger,	body []byte, rpc string) ([]byte, error) {
+func executeHTTPRequestWithResponse(ctx context.Context, client *http.Client, req *http.Request, logger *slog.Logger, body []byte, rpc string) ([]byte, *http.Response, error) {
 	logger.DebugContext(ctx, "api request", "serviceName", serviceName, "rpcName", rpc, "request", internallog.HTTPRequest(req, body))
 	resp, err := client.Do(req)
 	if err != nil{
-		return nil, err
+		return nil, nil, err
 	}
 	defer resp.Body.Close()
 	buf, err := io.ReadAll(resp.Body)
 	if err != nil {
-		return nil, err
+		return nil, nil, err
 	}
 	logger.DebugContext(ctx, "api response", "serviceName", serviceName, "rpcName", rpc, "response", internallog.HTTPResponse(resp, buf))
 	if err = googleapi.CheckResponse(resp); err != nil {
-		return nil, err
+		return nil, nil, err
 	}
-	return buf, nil
+	return buf, resp, nil
+}
+
+func executeHTTPRequest(ctx context.Context, client *http.Client, req *http.Request, logger *slog.Logger, body []byte, rpc string) ([]byte, error) {
+	buf, _, err := executeHTTPRequestWithResponse(ctx, client, req, logger, body, rpc)
+	return buf, err
 }
 
 func executeStreamingHTTPRequest(ctx context.Context, client *http.Client, req *http.Request, logger *slog.Logger, body []byte, rpc string) (*http.Response, error) {
diff --git a/internal/gengapic/testdata/helpers_no_scopes.want b/internal/gengapic/testdata/helpers_no_scopes.want
index b596b1e..d96b6e0 100644
--- a/internal/gengapic/testdata/helpers_no_scopes.want
+++ b/internal/gengapic/testdata/helpers_no_scopes.want
@@ -20,22 +20,27 @@ func DefaultAuthScopes() []string {
 	}
 }
 
-func executeHTTPRequest(ctx context.Context, client *http.Client, req *http.Request, logger *slog.Logger,	body []byte, rpc string) ([]byte, error) {
+func executeHTTPRequestWithResponse(ctx context.Context, client *http.Client, req *http.Request, logger *slog.Logger, body []byte, rpc string) ([]byte, *http.Response, error) {
 	logger.DebugContext(ctx, "api request", "serviceName", serviceName, "rpcName", rpc, "request", internallog.HTTPRequest(req, body))
 	resp, err := client.Do(req)
 	if err != nil{
-		return nil, err
+		return nil, nil, err
 	}
 	defer resp.Body.Close()
 	buf, err := io.ReadAll(resp.Body)
 	if err != nil {
-		return nil, err
+		return nil, nil, err
 	}
 	logger.DebugContext(ctx, "api response", "serviceName", serviceName, "rpcName", rpc, "response", internallog.HTTPResponse(resp, buf))
 	if err = googleapi.CheckResponse(resp); err != nil {
-		return nil, err
+		return nil, nil, err
 	}
-	return buf, nil
+	return buf, resp, nil
+}
+
+func executeHTTPRequest(ctx context.Context, client *http.Client, req *http.Request, logger *slog.Logger, body []byte, rpc string) ([]byte, error) {
+	buf, _, err := executeHTTPRequestWithResponse(ctx, client, req, logger, body, rpc)
+	return buf, err
 }
 
 func executeStreamingHTTPRequest(ctx context.Context, client *http.Client, req *http.Request, logger *slog.Logger, body []byte, rpc string) (*http.Response, error) {
diff --git a/internal/gengapic/testdata/rest_HttpBodyRPC.want b/internal/gengapic/testdata/rest_HttpBodyRPC.want
index 1d7d5d5..691d0a4 100644
--- a/internal/gengapic/testdata/rest_HttpBodyRPC.want
+++ b/internal/gengapic/testdata/rest_HttpBodyRPC.want
@@ -39,7 +39,7 @@ func (c *fooRESTClient) HttpBodyRPC(ctx context.Context, req *foopb.Foo, opts ..
 		httpReq = httpReq.WithContext(ctx)
 		httpReq.Header = headers
 
-		buf, err := executeHTTPRequest(ctx, c.httpClient, httpReq, c.logger, jsonReq, "HttpBodyRPC")
+		buf, httpRsp, err := executeHTTPRequestWithResponse(ctx, c.httpClient, httpReq, c.logger, jsonReq, "HttpBodyRPC")
 		if err != nil{
 			return err
 		}