Repository: cloudflare/cloudflare-go (go)

Issue:
Change UpdateDNSRecord to also return the DNSRecordResponse 
### Current cloudflare-go version

v0.63.0

### Description

Change [UpdateDNSRecord](https://github.com/cloudflare/cloudflare-go/blob/e41c0a2a615b8ee946b5ddf3698fb2181de0485d/dns.go#L230) return type from just `error` to `(*DNSRecordResponse, error)` (and consequently returning the `DNSRecordResponse` that is [already being received](https://github.com/cloudflare/cloudflare-go/blob/e41c0a2a615b8ee946b5ddf3698fb2181de0485d/dns.go#L247))

The proposed change would make this method consistent with:
- the [update DNS Record](https://developers.cloudflare.com/api/operations/dns-records-for-a-zone-update-dns-record) endpoint being hit, which returns the updated record in its response
- [CreateDNSRecord](https://github.com/cloudflare/cloudflare-go/blob/e41c0a2a615b8ee946b5ddf3698fb2181de0485d/dns.go#L130) -- similar to how [CreateWorkerRoute](https://github.com/cloudflare/cloudflare-go/blob/e41c0a2a615b8ee946b5ddf3698fb2181de0485d/workers_routes.go#L31)'s return type is consistent with [UpdateWorkerRoute](https://github.com/cloudflare/cloudflare-go/blob/e41c0a2a615b8ee946b5ddf3698fb2181de0485d/workers_routes.go#L137)



### Use cases

Handling `CreateDNSRecord` and `UpdateDNSRecord`'s responses in a uniform way.

In my particular case, I need to create/update a DNS record whenever I create/update a worker route (in order to automatically generate a new certificate, as I'm using [Total TLS](https://developers.cloudflare.com/ssl/edge-certificates/additional-options/total-tls/)). 
Since these pairs of methods (`Create/UpdateDNSRecord` and `Create/UpdateWorkerRoute`) are somewhat similar, it would be nice for their signatures/return types to be consistent with each other, enabling one to write code that mirrors those similarities.

### Potential cloudflare-go usage

```go
// the main goal is that this function returns a cloudflare.DNSRecord, regardless of whether
// it was created or updated.
func createOrUpdateDNSRecord(ctx context.Context, someParam SomeParam) (cloudflare.DNSRecord, error) {
        // look up dns record somewhere, based on some parameter that doesn't matter
        dnsRecord := findDnsRecord(someParam) 

	proxied := true

	var resp *cloudflare.DNSRecordResponse
	var err error
	if dnsRecord == nil {
		resp, err = cfApi.CreateDNSRecord(ctx, cloudflare.ZoneIdentifier(ZONE_ID), cloudflare.CreateDNSRecordParams{...})
	} else {
		resp, err = cfApi.UpdateDNSRecord(ctx, cloudflare.ZoneIdentifier(ZONE_ID), cloudflare.UpdateDNSRecordParams{...})
	}
        return resp.Result, err
}
```


### References

_No response_

Pull request:
Update Create/UpdateDNSRecord method signatures
**Disclaimer:** this is my first ever contribution to an open-source project, so any suggestions that help me improve my PR game are very welcome.

## Description

Changes `CreateDNSRecord` and `UpdateDNSRecord` method signatures such that they both return `(DNSRecord, error)`.
Closes #1239 

## Types of changes

What sort of change does your code introduce/modify?

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing functionality to change)

## Checklist:

- [x] My code follows the code style of this project.
- [x] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [ ] I have added tests to cover my changes.
- [x] All new and existing tests passed.
- [x] This change is using publicly documented (api.cloudflare.com or developers.cloudflare.com) and stable APIs.



Patch:
diff --git a/.changelog/1243.txt b/.changelog/1243.txt
new file mode 100644
index 000000000..f5c0728ec
--- /dev/null
+++ b/.changelog/1243.txt
@@ -0,0 +1,3 @@
+```release-note:breaking-change
+dns: Changed Create/UpdateDNSRecord method signatures to return (DNSRecord, error)
+```
\ No newline at end of file
diff --git a/cmd/flarectl/dns.go b/cmd/flarectl/dns.go
index fd5a52816..5199e1027 100644
--- a/cmd/flarectl/dns.go
+++ b/cmd/flarectl/dns.go
@@ -50,14 +50,14 @@ func dnsCreate(c *cli.Context) error {
 		Proxied:  &proxy,
 		Priority: &priority,
 	}
-	resp, err := api.CreateDNSRecord(context.Background(), cloudflare.ZoneIdentifier(zoneID), record)
+	result, err := api.CreateDNSRecord(context.Background(), cloudflare.ZoneIdentifier(zoneID), record)
 	if err != nil {
 		fmt.Fprintln(os.Stderr, "Error creating DNS record: ", err)
 		return err
 	}
 
 	output := [][]string{
-		formatDNSRecord(resp.Result),
+		formatDNSRecord(result),
 	}
 
 	writeTable(c, output, "ID", "Name", "Type", "Content", "TTL", "Proxiable", "Proxy", "Locked")
@@ -90,7 +90,7 @@ func dnsCreateOrUpdate(c *cli.Context) error {
 		return err
 	}
 
-	var resp *cloudflare.DNSRecordResponse
+	var result cloudflare.DNSRecord
 	if len(records) > 0 {
 		// Record exists - find the ID and update it.
 		// This is imprecise without knowing the original content; if a label
@@ -105,21 +105,11 @@ func dnsCreateOrUpdate(c *cli.Context) error {
 				rr.Proxied = &proxy
 				rr.Priority = &priority
 
-				err := api.UpdateDNSRecord(context.Background(), cloudflare.ZoneIdentifier(zoneID), rr)
+				result, err = api.UpdateDNSRecord(context.Background(), cloudflare.ZoneIdentifier(zoneID), rr)
 				if err != nil {
 					fmt.Println("Error updating DNS record:", err)
 					return err
 				}
-				resp = &cloudflare.DNSRecordResponse{
-					Result: cloudflare.DNSRecord{
-						ID:      rr.ID,
-						Name:    rr.Name,
-						Type:    rr.Type,
-						Content: rr.Content,
-						TTL:     rr.TTL,
-						Proxied: &proxy,
-					},
-				}
 			}
 		}
 	} else {
@@ -131,7 +121,7 @@ func dnsCreateOrUpdate(c *cli.Context) error {
 		rr.Proxied = &proxy
 		rr.Priority = &priority
 		// TODO: Print the response.
-		resp, err = api.CreateDNSRecord(context.Background(), cloudflare.ZoneIdentifier(zoneID), rr)
+		result, err = api.CreateDNSRecord(context.Background(), cloudflare.ZoneIdentifier(zoneID), rr)
 		if err != nil {
 			fmt.Println("Error creating DNS record:", err)
 			return err
@@ -139,7 +129,7 @@ func dnsCreateOrUpdate(c *cli.Context) error {
 	}
 
 	output := [][]string{
-		formatDNSRecord(resp.Result),
+		formatDNSRecord(result),
 	}
 
 	writeTable(c, output, "ID", "Name", "Type", "Content", "TTL", "Proxiable", "Proxy", "Locked")
@@ -176,7 +166,7 @@ func dnsUpdate(c *cli.Context) error {
 		Proxied:  &proxy,
 		Priority: &priority,
 	}
-	err = api.UpdateDNSRecord(context.Background(), cloudflare.ZoneIdentifier(zoneID), record)
+	_, err = api.UpdateDNSRecord(context.Background(), cloudflare.ZoneIdentifier(zoneID), record)
 	if err != nil {
 		fmt.Fprintln(os.Stderr, "Error updating DNS record: ", err)
 		return err
diff --git a/dns.go b/dns.go
index d7bd308d7..afc47b66b 100644
--- a/dns.go
+++ b/dns.go
@@ -127,25 +127,25 @@ type CreateDNSRecordParams struct {
 // CreateDNSRecord creates a DNS record for the zone identifier.
 //
 // API reference: https://api.cloudflare.com/#dns-records-for-a-zone-create-dns-record
-func (api *API) CreateDNSRecord(ctx context.Context, rc *ResourceContainer, params CreateDNSRecordParams) (*DNSRecordResponse, error) {
+func (api *API) CreateDNSRecord(ctx context.Context, rc *ResourceContainer, params CreateDNSRecordParams) (DNSRecord, error) {
 	if rc.Identifier == "" {
-		return nil, ErrMissingZoneID
+		return DNSRecord{}, ErrMissingZoneID
 	}
 	params.Name = toUTS46ASCII(params.Name)
 
 	uri := fmt.Sprintf("/zones/%s/dns_records", rc.Identifier)
 	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
 	if err != nil {
-		return nil, err
+		return DNSRecord{}, err
 	}
 
 	var recordResp *DNSRecordResponse
 	err = json.Unmarshal(res, &recordResp)
 	if err != nil {
-		return nil, fmt.Errorf("%s: %w", errUnmarshalError, err)
+		return DNSRecord{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
 	}
 
-	return recordResp, nil
+	return recordResp.Result, nil
 }
 
 // ListDNSRecords returns a slice of DNS records for the given zone identifier.
@@ -227,13 +227,13 @@ func (api *API) GetDNSRecord(ctx context.Context, rc *ResourceContainer, recordI
 // identifiers.
 //
 // API reference: https://api.cloudflare.com/#dns-records-for-a-zone-update-dns-record
-func (api *API) UpdateDNSRecord(ctx context.Context, rc *ResourceContainer, params UpdateDNSRecordParams) error {
+func (api *API) UpdateDNSRecord(ctx context.Context, rc *ResourceContainer, params UpdateDNSRecordParams) (DNSRecord, error) {
 	if rc.Identifier == "" {
-		return ErrMissingZoneID
+		return DNSRecord{}, ErrMissingZoneID
 	}
 
 	if params.ID == "" {
-		return ErrMissingDNSRecordID
+		return DNSRecord{}, ErrMissingDNSRecordID
 	}
 
 	params.Name = toUTS46ASCII(params.Name)
@@ -241,14 +241,16 @@ func (api *API) UpdateDNSRecord(ctx context.Context, rc *ResourceContainer, para
 	uri := fmt.Sprintf("/zones/%s/dns_records/%s", rc.Identifier, params.ID)
 	res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, params)
 	if err != nil {
-		return err
+		return DNSRecord{}, err
 	}
-	var r DNSRecordResponse
-	err = json.Unmarshal(res, &r)
+
+	var recordResp *DNSRecordResponse
+	err = json.Unmarshal(res, &recordResp)
 	if err != nil {
-		return fmt.Errorf("%s: %w", errUnmarshalError, err)
+		return DNSRecord{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
 	}
-	return nil
+
+	return recordResp.Result, nil
 }
 
 // DeleteDNSRecord deletes a single DNS record for the given zone & record


Test patch:
diff --git a/dns_test.go b/dns_test.go
index 46871f162..3145a764c 100644
--- a/dns_test.go
+++ b/dns_test.go
@@ -116,26 +116,23 @@ func TestCreateDNSRecord(t *testing.T) {
 
 	createdOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z")
 	modifiedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z")
-	want := &DNSRecordResponse{
-		Result: DNSRecord{
-			ID:         "372e67954025e0ba6aaa6d586b9e0b59",
-			Type:       asciiInput.Type,
-			Name:       asciiInput.Name,
-			Content:    asciiInput.Content,
-			Proxiable:  true,
-			Proxied:    asciiInput.Proxied,
-			TTL:        asciiInput.TTL,
-			ZoneID:     testZoneID,
-			ZoneName:   "example.com",
-			CreatedOn:  createdOn,
-			ModifiedOn: modifiedOn,
-			Data:       map[string]interface{}{},
-			Meta: map[string]interface{}{
-				"auto_added": true,
-				"source":     "primary",
-			},
+	want := DNSRecord{
+		ID:         "372e67954025e0ba6aaa6d586b9e0b59",
+		Type:       asciiInput.Type,
+		Name:       asciiInput.Name,
+		Content:    asciiInput.Content,
+		Proxiable:  true,
+		Proxied:    asciiInput.Proxied,
+		TTL:        asciiInput.TTL,
+		ZoneID:     testZoneID,
+		ZoneName:   "example.com",
+		CreatedOn:  createdOn,
+		ModifiedOn: modifiedOn,
+		Data:       map[string]interface{}{},
+		Meta: map[string]interface{}{
+			"auto_added": true,
+			"source":     "primary",
 		},
-		Response: Response{Success: true, Errors: []ResponseInfo{}, Messages: []ResponseInfo{}},
 	}
 
 	_, err := client.CreateDNSRecord(context.Background(), ZoneIdentifier(""), CreateDNSRecordParams{})
@@ -549,13 +546,13 @@ func TestUpdateDNSRecord(t *testing.T) {
 
 	mux.HandleFunc("/zones/"+testZoneID+"/dns_records/"+dnsRecordID, handler)
 
-	err := client.UpdateDNSRecord(context.Background(), ZoneIdentifier(""), UpdateDNSRecordParams{ID: dnsRecordID})
+	_, err := client.UpdateDNSRecord(context.Background(), ZoneIdentifier(""), UpdateDNSRecordParams{ID: dnsRecordID})
 	assert.ErrorIs(t, err, ErrMissingZoneID)
 
-	err = client.UpdateDNSRecord(context.Background(), ZoneIdentifier(testZoneID), UpdateDNSRecordParams{})
+	_, err = client.UpdateDNSRecord(context.Background(), ZoneIdentifier(testZoneID), UpdateDNSRecordParams{})
 	assert.ErrorIs(t, err, ErrMissingDNSRecordID)
 
-	err = client.UpdateDNSRecord(context.Background(), ZoneIdentifier(testZoneID), UpdateDNSRecordParams{
+	_, err = client.UpdateDNSRecord(context.Background(), ZoneIdentifier(testZoneID), UpdateDNSRecordParams{
 		ID:      dnsRecordID,
 		Type:    "A",
 		Name:    "😺.example.com",
@@ -617,7 +614,7 @@ func TestUpdateDNSRecord_ClearComment(t *testing.T) {
 
 	mux.HandleFunc("/zones/"+testZoneID+"/dns_records/"+dnsRecordID, handler)
 
-	err := client.UpdateDNSRecord(context.Background(), ZoneIdentifier(testZoneID), UpdateDNSRecordParams{
+	_, err := client.UpdateDNSRecord(context.Background(), ZoneIdentifier(testZoneID), UpdateDNSRecordParams{
 		ID:      dnsRecordID,
 		Comment: "",
 	})