Skip to content

Commit

Permalink
fix(products): Improve API usability.
Browse files Browse the repository at this point in the history
* Add 'EnableOutput' type aliases in each product, so that users of
  the API don't need to know whether that product has its own
  EnableOutput or not. Add 'NewEnableOutput' function so that users of
  the API can easily construct mock output instances.

* Add 'ProductName' constant in each product, so that users of the API
  will have access to the canonical name of the product along with its
  product_id.

* Change package names to conform to Go guidelines (remove underscores).

* Change APIs to accept and return by-value instead of by-pointer, as
  using by-pointer structures can be difficult in generic parameter
  contexts and the structures involved are small (so there is no real
  benefit to avoiding by-value passing).
  • Loading branch information
kpfleming committed Jan 14, 2025
1 parent 824cab9 commit 7d432c5
Show file tree
Hide file tree
Showing 112 changed files with 509 additions and 386 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package image_optimizer_default_settings_test
package imageoptimizerdefaultsettings_test

import (
"strings"
"testing"

"github.com/fastly/go-fastly/v9/fastly"
"github.com/fastly/go-fastly/v9/fastly/products/image_optimizer"
"github.com/fastly/go-fastly/v9/fastly/products/imageoptimizer"
)

// TestClient_ImageOptimizerDefaultSettings tests the Image Optimizer Default Settings API
Expand All @@ -23,7 +23,7 @@ func TestClient_ImageOptimizerDefaultSettings(t *testing.T) {

// Enable IO
fastly.Record(t, fixtureBase+"enable_product", func(c *fastly.Client) {
_, err = image_optimizer.Enable(c, fastly.TestDeliveryServiceID)
_, err = imageoptimizer.Enable(c, fastly.TestDeliveryServiceID)
})
if err != nil {
t.Fatal(err)
Expand All @@ -32,7 +32,7 @@ func TestClient_ImageOptimizerDefaultSettings(t *testing.T) {
// Ensure we disable IO on the service after the test
defer func() {
fastly.Record(t, fixtureBase+"disable_product", func(c *fastly.Client) {
_, err = image_optimizer.Enable(c, fastly.TestDeliveryServiceID)
_, err = imageoptimizer.Enable(c, fastly.TestDeliveryServiceID)

if err != nil {
t.Fatal(err)
Expand Down
38 changes: 0 additions & 38 deletions fastly/products/api_output.go

This file was deleted.

3 changes: 0 additions & 3 deletions fastly/products/bot_management/doc.go

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
package bot_management
package botmanagement

import (
"github.com/fastly/go-fastly/v9/fastly"
"github.com/fastly/go-fastly/v9/fastly/products"
"github.com/fastly/go-fastly/v9/internal/productcore"
)

const ProductID = "bot_management"
const (
ProductID = "bot_management"
ProductName = "Bot Management"
)

type EnableOutput = products.EnableOutput

// Get gets the status of the Bot Management product on the service.
func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) {
return productcore.Get[*products.EnableOutput](&productcore.GetInput{
func Get(c *fastly.Client, serviceID string) (EnableOutput, error) {
return productcore.Get[EnableOutput](&productcore.GetInput{
Client: c,
ProductID: ProductID,
ServiceID: serviceID,
})
}

// Enable enables the Bot Management product on the service.
func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) {
return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{
func Enable(c *fastly.Client, serviceID string) (EnableOutput, error) {
return productcore.Put[EnableOutput](&productcore.PutInput[products.NullInput]{
Client: c,
ProductID: ProductID,
ServiceID: serviceID,
Expand All @@ -34,3 +39,9 @@ func Disable(c *fastly.Client, serviceID string) error {
ServiceID: serviceID,
})
}

// NewEnableOutput is used to construct mock API output structures for
// use in tests.
func NewEnableOutput(serviceID string) EnableOutput {
return products.NewEnableOutput(ProductID, serviceID)
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package bot_management_test
package botmanagement_test

import (
"testing"

"github.com/fastly/go-fastly/v9/fastly"
"github.com/fastly/go-fastly/v9/fastly/products"
"github.com/fastly/go-fastly/v9/fastly/products/bot_management"
"github.com/fastly/go-fastly/v9/fastly/products/botmanagement"
"github.com/fastly/go-fastly/v9/internal/productcore"
"github.com/fastly/go-fastly/v9/internal/test_utils"
)
Expand All @@ -15,36 +15,36 @@ var serviceID = fastly.TestDeliveryServiceID
var functionalTests = []*test_utils.FunctionalTest{
productcore.NewDisableTest(&productcore.DisableTestInput{
Phase: "ensure disabled before testing",
OpFn: bot_management.Disable,
OpFn: botmanagement.Disable,
ServiceID: serviceID,
IgnoreFailure: true,
}),
productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{
productcore.NewGetTest(&productcore.GetTestInput[botmanagement.EnableOutput]{
Phase: "before enablement",
OpFn: bot_management.Get,
ProductID: bot_management.ProductID,
OpFn: botmanagement.Get,
ProductID: botmanagement.ProductID,
ServiceID: serviceID,
ExpectFailure: true,
}),
productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *productcore.NullInput]{
OpNoInputFn: bot_management.Enable,
ProductID: bot_management.ProductID,
productcore.NewEnableTest(&productcore.EnableTestInput[botmanagement.EnableOutput, products.NullInput]{
OpNoInputFn: botmanagement.Enable,
ProductID: botmanagement.ProductID,
ServiceID: serviceID,
}),
productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{
productcore.NewGetTest(&productcore.GetTestInput[botmanagement.EnableOutput]{
Phase: "after enablement",
OpFn: bot_management.Get,
ProductID: bot_management.ProductID,
OpFn: botmanagement.Get,
ProductID: botmanagement.ProductID,
ServiceID: serviceID,
}),
productcore.NewDisableTest(&productcore.DisableTestInput{
OpFn: bot_management.Disable,
OpFn: botmanagement.Disable,
ServiceID: serviceID,
}),
productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{
productcore.NewGetTest(&productcore.GetTestInput[botmanagement.EnableOutput]{
Phase: "after disablement",
OpFn: bot_management.Get,
ProductID: bot_management.ProductID,
OpFn: botmanagement.Get,
ProductID: botmanagement.ProductID,
ServiceID: serviceID,
ExpectFailure: true,
}),
Expand Down
3 changes: 3 additions & 0 deletions fastly/products/botmanagement/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Package botmanagement contains API operations to enable and
// disable the Bot Management product on a service
package botmanagement
3 changes: 0 additions & 3 deletions fastly/products/brotli_compression/doc.go

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
package brotli_compression
package brotlicompression

import (
"github.com/fastly/go-fastly/v9/fastly"
"github.com/fastly/go-fastly/v9/fastly/products"
"github.com/fastly/go-fastly/v9/internal/productcore"
)

const ProductID = "brotli_compression"
const (
ProductID = "brotli_compression"
ProductName = "Brotli Compression"
)

type EnableOutput = products.EnableOutput

// Get gets the status of the Brotli Compression product on the service.
func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) {
return productcore.Get[*products.EnableOutput](&productcore.GetInput{
func Get(c *fastly.Client, serviceID string) (EnableOutput, error) {
return productcore.Get[EnableOutput](&productcore.GetInput{
Client: c,
ProductID: ProductID,
ServiceID: serviceID,
})
}

// Enable enables the Brotli Compression product on the service.
func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) {
return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{
func Enable(c *fastly.Client, serviceID string) (EnableOutput, error) {
return productcore.Put[EnableOutput](&productcore.PutInput[products.NullInput]{
Client: c,
ProductID: ProductID,
ServiceID: serviceID,
Expand All @@ -34,3 +39,9 @@ func Disable(c *fastly.Client, serviceID string) error {
ServiceID: serviceID,
})
}

// NewEnableOutput is used to construct mock API output structures for
// use in tests.
func NewEnableOutput(serviceID string) EnableOutput {
return products.NewEnableOutput(ProductID, serviceID)
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package brotli_compression_test
package brotlicompression_test

import (
"testing"

"github.com/fastly/go-fastly/v9/fastly"
"github.com/fastly/go-fastly/v9/fastly/products"
"github.com/fastly/go-fastly/v9/fastly/products/brotli_compression"
"github.com/fastly/go-fastly/v9/fastly/products/brotlicompression"
"github.com/fastly/go-fastly/v9/internal/productcore"
"github.com/fastly/go-fastly/v9/internal/test_utils"
)
Expand All @@ -15,36 +15,36 @@ var serviceID = fastly.TestDeliveryServiceID
var functionalTests = []*test_utils.FunctionalTest{
productcore.NewDisableTest(&productcore.DisableTestInput{
Phase: "ensure disabled before testing",
OpFn: brotli_compression.Disable,
OpFn: brotlicompression.Disable,
ServiceID: serviceID,
IgnoreFailure: true,
}),
productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{
productcore.NewGetTest(&productcore.GetTestInput[brotlicompression.EnableOutput]{
Phase: "before enablement",
OpFn: brotli_compression.Get,
ProductID: brotli_compression.ProductID,
OpFn: brotlicompression.Get,
ProductID: brotlicompression.ProductID,
ServiceID: serviceID,
ExpectFailure: true,
}),
productcore.NewEnableTest(&productcore.EnableTestInput[*products.EnableOutput, *productcore.NullInput]{
OpNoInputFn: brotli_compression.Enable,
ProductID: brotli_compression.ProductID,
productcore.NewEnableTest(&productcore.EnableTestInput[brotlicompression.EnableOutput, products.NullInput]{
OpNoInputFn: brotlicompression.Enable,
ProductID: brotlicompression.ProductID,
ServiceID: serviceID,
}),
productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{
productcore.NewGetTest(&productcore.GetTestInput[brotlicompression.EnableOutput]{
Phase: "after enablement",
OpFn: brotli_compression.Get,
ProductID: brotli_compression.ProductID,
OpFn: brotlicompression.Get,
ProductID: brotlicompression.ProductID,
ServiceID: serviceID,
}),
productcore.NewDisableTest(&productcore.DisableTestInput{
OpFn: brotli_compression.Disable,
OpFn: brotlicompression.Disable,
ServiceID: serviceID,
}),
productcore.NewGetTest(&productcore.GetTestInput[*products.EnableOutput]{
productcore.NewGetTest(&productcore.GetTestInput[brotlicompression.EnableOutput]{
Phase: "after disablement",
OpFn: brotli_compression.Get,
ProductID: brotli_compression.ProductID,
OpFn: brotlicompression.Get,
ProductID: brotlicompression.ProductID,
ServiceID: serviceID,
ExpectFailure: true,
}),
Expand Down
3 changes: 3 additions & 0 deletions fastly/products/brotlicompression/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Package brotlicompression contains API operations to enable and
// disable the Brotli Compression product on a service
package brotlicompression
3 changes: 0 additions & 3 deletions fastly/products/ddos_protection/doc.go

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package ddos_protection
package ddosprotection

import (
"github.com/fastly/go-fastly/v9/fastly"
"github.com/fastly/go-fastly/v9/fastly/products"
"github.com/fastly/go-fastly/v9/internal/productcore"
)

const ProductID = "ddos_protection"
const (
ProductID = "ddos_protection"
ProductName = "DDoS Protection"
)

type EnableOutput = products.EnableOutput

// ErrMissingMode is the error returned by the UpdateConfiguration
// function when it is passed a ConfigureInput struct with a mode
Expand All @@ -27,17 +32,17 @@ type configureOutputNested struct {
}

// Get gets the status of the DDoS Protection product on the service.
func Get(c *fastly.Client, serviceID string) (*products.EnableOutput, error) {
return productcore.Get[*products.EnableOutput](&productcore.GetInput{
func Get(c *fastly.Client, serviceID string) (EnableOutput, error) {
return productcore.Get[EnableOutput](&productcore.GetInput{
Client: c,
ProductID: ProductID,
ServiceID: serviceID,
})
}

// Enable enables the DDoS Protection product on the service.
func Enable(c *fastly.Client, serviceID string) (*products.EnableOutput, error) {
return productcore.Put[*products.EnableOutput](&productcore.PutInput[*productcore.NullInput]{
func Enable(c *fastly.Client, serviceID string) (EnableOutput, error) {
return productcore.Put[EnableOutput](&productcore.PutInput[products.NullInput]{
Client: c,
ProductID: ProductID,
ServiceID: serviceID,
Expand All @@ -54,8 +59,8 @@ func Disable(c *fastly.Client, serviceID string) error {
}

// GetConfiguration gets the configuration of the DDoS Protection product on the service.
func GetConfiguration(c *fastly.Client, serviceID string) (*ConfigureOutput, error) {
return productcore.Get[*ConfigureOutput](&productcore.GetInput{
func GetConfiguration(c *fastly.Client, serviceID string) (ConfigureOutput, error) {
return productcore.Get[ConfigureOutput](&productcore.GetInput{
Client: c,
ProductID: ProductID,
ServiceID: serviceID,
Expand All @@ -64,16 +69,22 @@ func GetConfiguration(c *fastly.Client, serviceID string) (*ConfigureOutput, err
}

// UpdateConfiguration updates the configuration of the DDoS Protection product on the service.
func UpdateConfiguration(c *fastly.Client, serviceID string, i *ConfigureInput) (*ConfigureOutput, error) {
func UpdateConfiguration(c *fastly.Client, serviceID string, i ConfigureInput) (ConfigureOutput, error) {
if i.Mode == "" {
return nil, ErrMissingMode
return ConfigureOutput{}, ErrMissingMode
}

return productcore.Patch[*ConfigureOutput](&productcore.PatchInput[*ConfigureInput]{
return productcore.Patch[ConfigureOutput](&productcore.PatchInput[ConfigureInput]{
Client: c,
ProductID: ProductID,
ServiceID: serviceID,
URLComponents: []string{"configuration"},
Input: i,
})
}

// NewEnableOutput is used to construct mock API output structures for
// use in tests.
func NewEnableOutput(serviceID string) EnableOutput {
return products.NewEnableOutput(ProductID, serviceID)
}
Loading

0 comments on commit 7d432c5

Please sign in to comment.