From 01e199fb1da8cf12e7676cebbc8e848a5d499edd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Grzegorz=20Burzy=C5=84ski?= <czeslavo@gmail.com>
Date: Tue, 25 Jun 2024 16:28:11 +0200
Subject: [PATCH] feat: drop resp body from ReloadDeclarativeRawConfig
 signature

---
 CHANGELOG.md        | 13 +++++++++++++
 kong/client.go      | 14 +++++++-------
 kong/client_test.go | 14 +++++---------
 3 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 011797e5..9e6f960c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,7 @@
 # Table of Contents
 
+- [v0.57.0](#v0570)
+- [v0.56.0](#v0560)
 - [v0.55.0](#v0550)
 - [v0.54.0](#v0540)
 - [v0.53.0](#v0530)
@@ -67,6 +69,15 @@
 - [0.2.0](#020)
 - [0.1.0](#010)
 
+## [v0.57.0]
+
+> Release date: 2024/06/25
+
+- **Breaking change** `ReloadDeclarativeRawConfig` now doesn't return a response body
+  as its first return value - the body can be obtained from `APIError` returned when
+  the response is not successful.
+  [#453](https://github.com/Kong/go-kong/pull/453)
+
 ## [v0.56.0]
 
 > Release date: 2024/06/25
@@ -894,6 +905,8 @@ authentication credentials in Kong.
   releases of Kong since every release of Kong is introducing breaking changes
   to the Admin API.
 
+[v0.57.0]: https://github.com/Kong/go-kong/compare/v0.56.0...v0.57.0
+[v0.56.0]: https://github.com/Kong/go-kong/compare/v0.55.0...v0.56.0
 [v0.55.0]: https://github.com/Kong/go-kong/compare/v0.54.0...v0.55.0
 [v0.54.0]: https://github.com/Kong/go-kong/compare/v0.53.0...v0.54.0
 [v0.53.0]: https://github.com/Kong/go-kong/compare/v0.52.0...v0.53.0
diff --git a/kong/client.go b/kong/client.go
index 907c6b35..df98a232 100644
--- a/kong/client.go
+++ b/kong/client.go
@@ -470,13 +470,13 @@ func (c *Client) BaseRootURL() string {
 // API endpoint using the provided reader which should contain the JSON
 // serialized body that adheres to the configuration format specified at:
 // https://docs.konghq.com/gateway/latest/production/deployment-topologies/db-less-and-declarative-config/#declarative-configuration-format
-// It returns the response body and an error, if it encounters any.
+// It returns APIError with a response body in case it receives a valid HTTP response with <200 or >=400 status codes.
 func (c *Client) ReloadDeclarativeRawConfig(
 	ctx context.Context,
 	config io.Reader,
 	checkHash bool,
 	flattenErrors bool,
-) ([]byte, error) {
+) error {
 	type sendConfigParams struct {
 		CheckHash     int `url:"check_hash,omitempty"`
 		FlattenErrors int `url:"flatten_errors,omitempty"`
@@ -496,22 +496,22 @@ func (c *Client) ReloadDeclarativeRawConfig(
 		config,
 	)
 	if err != nil {
-		return nil, fmt.Errorf("creating new HTTP request for /config: %w", err)
+		return fmt.Errorf("creating new HTTP request for /config: %w", err)
 	}
 
 	resp, err := c.DoRAW(ctx, req)
 	if err != nil {
-		return nil, fmt.Errorf("failed posting new config to /config: %w", err)
+		return fmt.Errorf("failed posting new config to /config: %w", err)
 	}
 	defer resp.Body.Close()
 
 	b, err := io.ReadAll(resp.Body)
 	if err != nil {
-		return nil, fmt.Errorf("could not read /config %d status response body: %w", resp.StatusCode, err)
+		return fmt.Errorf("could not read /config %d status response body: %w", resp.StatusCode, err)
 	}
 	if resp.StatusCode < 200 || resp.StatusCode >= 400 {
-		return b, NewAPIErrorWithRaw(resp.StatusCode, "failed posting new config to /config", b)
+		return NewAPIErrorWithRaw(resp.StatusCode, "failed posting new config to /config", b)
 	}
 
-	return b, nil
+	return nil
 }
diff --git a/kong/client_test.go b/kong/client_test.go
index dcbfb632..f4bd1bc0 100644
--- a/kong/client_test.go
+++ b/kong/client_test.go
@@ -361,20 +361,16 @@ func TestReloadDeclarativeRawConfig(t *testing.T) {
 			b, err := json.Marshal(tt.config)
 			require.NoError(t, err)
 
-			body, err := client.ReloadDeclarativeRawConfig(ctx, bytes.NewBuffer(b), true, flattenErrors)
+			err = client.ReloadDeclarativeRawConfig(ctx, bytes.NewBuffer(b), true, flattenErrors)
 
 			if tt.wantErr {
 				assert.Error(t, err)
-				require.IsType(t, err, &APIError{}, "expected APIError")
+				apiErr := &APIError{}
+				assert.True(t, errors.As(err, &apiErr))
+				assert.NotEmpty(t, apiErr.Raw(), "expected non-empty response body in APIError")
 			} else {
 				assert.NoError(t, err)
 			}
-
-			// this is somewhat untrue: network or HTTP-level failures _can_ result in a nil response body. however,
-			// none of our test cases should cause network or HTTP-level failures, so fail if they do occur. if this
-			// _does_ encounter such a failure, we need to investigate and either update tests or fix some upstream bug
-			// if it's not some transient issue with the testing environment
-			require.NotNilf(t, body, "body was nil; should never be nil")
 		})
 	}
 }
@@ -388,7 +384,7 @@ func TestReloadDeclarativeRawConfig_NetworkErrorDoesntReturnAPIError(t *testing.
 	require.NoError(t, err)
 	require.NotNil(t, client)
 
-	_, err = client.ReloadDeclarativeRawConfig(context.Background(), bytes.NewReader([]byte("dummy-config")), true, true)
+	err = client.ReloadDeclarativeRawConfig(context.Background(), bytes.NewReader([]byte("dummy-config")), true, true)
 	require.Error(t, err)
 	require.False(t, errors.Is(err, &APIError{}), "expected error to not be an APIError")
 }