github.com/fastly/go-fastly/v6@v6.8.0/README.md (about) 1 # Go Fastly 2 3 [][latest] 4 5 [latest]: https://pkg.go.dev/github.com/fastly/go-fastly/v6/fastly 6 [v6]: https://pkg.go.dev/github.com/fastly/go-fastly/v6/fastly 7 [v5]: https://pkg.go.dev/github.com/fastly/go-fastly/v5/fastly 8 [v4]: https://pkg.go.dev/github.com/fastly/go-fastly/v4/fastly 9 [v3]: https://pkg.go.dev/github.com/fastly/go-fastly/v3/fastly 10 [v2]: https://pkg.go.dev/github.com/fastly/go-fastly/v2/fastly 11 [v1]: https://pkg.go.dev/github.com/fastly/go-fastly 12 13 Go Fastly is a Golang API client for interacting with most facets of the 14 [Fastly API](https://docs.fastly.com/api). 15 16 ## Installation 17 18 This is a client library, so there is nothing to install. But, it uses Go modules, 19 so you must be running Go 1.11 or higher. 20 21 ## Usage 22 23 ```go 24 import "github.com/fastly/go-fastly/v6/fastly" 25 ``` 26 27 ## Migrating from v1 to v2 28 29 The move from major version [1][v1] to [2][v2] has resulted in a couple of fundamental changes to the library: 30 31 - Consistent field name format for IDs and Versions (e.g. `DictionaryID`, `PoolID`, `ServiceID`, `ServiceVersion` etc). 32 - Input struct fields (for write/update operations) that are optional (i.e. `omitempty`) and use basic types, are now defined as pointers. 33 34 The move to more consistent field names in some cases will have resulted in the corresponding sentinel error name to be updated also. For example, `ServiceID` has resulted in a change from `ErrMissingService` to `ErrMissingServiceID`. 35 36 The change in type for [basic types](https://tour.golang.org/basics/11) that are optional on input structs related to write/update operations is designed to avoid unexpected behaviours when dealing with their zero value (see [this reference](https://willnorris.com/2014/05/go-rest-apis-and-pointers/) for more details). As part of this change we now provide [helper functions](./fastly/basictypes_helper.go) to assist with generating the new pointer types required. 37 38 > Note: some read/list operations require fields to be provided but if omitted a zero value will be used when marshaling the data structure into JSON. This too can cause confusion, which is why some input structs define their mandatory fields as pointers (to ensure that the backend can distinguish between a zero value and an omitted field). 39 40 ## Migrating from v2 to v3 41 42 There were a few breaking changes introduced in [`v3.0.0`][v3]: 43 44 1. A new `FieldError` abstraction for validating API struct fields. 45 2. Changing some mandatory fields to Optional (and vice-versa) to better support more _practical_ API usage. 46 3. Avoid generic ID field when more explicit naming would be clearer. 47 48 ## Examples 49 50 Fastly's API is designed to work in the following manner: 51 52 1. Create (or clone) a new configuration version for the service 53 2. Make any changes to the version 54 3. Validate the version 55 4. Activate the version 56 57 This flow using the Golang client looks like this: 58 59 ```go 60 package main 61 62 import ( 63 "fmt" 64 "log" 65 "os" 66 "github.com/fastly/go-fastly/v6/fastly" 67 ) 68 69 func main() { 70 // Create a client object. The client has no state, so it can be persisted 71 // and re-used. It is also safe to use concurrently due to its lack of state. 72 // There is also a DefaultClient() method that reads an environment variable. 73 // Please see the documentation for more information and details. 74 client, err := fastly.NewClient(os.Getenv("FASTLY_API_KEY")) 75 if err != nil { 76 log.Fatal(err) 77 } 78 79 // You can find the service ID in the Fastly web console. 80 var serviceID = "SERVICE_ID" 81 82 // We'll get the latest 'active' version by inspecting the service metadata and 83 // then finding which available version is the 'active' version. 84 service, err := client.GetService(&fastly.GetServiceInput{ 85 ID: serviceID, 86 }) 87 if err != nil { 88 log.Fatal(err) 89 } 90 91 // Let's acquire a service version to clone from. We'll start by searching for 92 // the latest 'active' version available, and if there are no active versions, 93 // then we'll clone from whatever is the latest version. 94 latest := service.Versions[len(service.Versions)-1] 95 for _, version := range service.Versions { 96 if version.Active { 97 latest = version 98 break 99 } 100 } 101 102 // Clone the latest version so we can make changes without affecting the 103 // active configuration. 104 version, err := client.CloneVersion(&fastly.CloneVersionInput{ 105 ServiceID: serviceID, 106 ServiceVersion: latest.Number, 107 }) 108 if err != nil { 109 log.Fatal(err) 110 } 111 112 // Now you can make any changes to the new version. In this example, we will add 113 // a new domain. 114 domain, err := client.CreateDomain(&fastly.CreateDomainInput{ 115 ServiceID: serviceID, 116 ServiceVersion: version.Number, 117 Name: "example.com", 118 }) 119 if err != nil { 120 log.Fatal(err) 121 } 122 123 // Output: "example.com" 124 fmt.Println("domain.Name:", domain.Name) 125 126 // And we will also add a new backend. 127 backend, err := client.CreateBackend(&fastly.CreateBackendInput{ 128 ServiceID: serviceID, 129 ServiceVersion: version.Number, 130 Name: "example-backend", 131 Address: "127.0.0.1", 132 Port: 80, 133 }) 134 if err != nil { 135 log.Fatal(err) 136 } 137 138 // Output: "example-backend" 139 fmt.Println("backend.Name:", backend.Name) 140 141 // Now we can validate that our version is valid. 142 valid, _, err := client.ValidateVersion(&fastly.ValidateVersionInput{ 143 ServiceID: serviceID, 144 ServiceVersion: version.Number, 145 }) 146 if err != nil { 147 log.Fatal(err) 148 } 149 if !valid { 150 log.Fatal("not valid version") 151 } 152 153 // Finally, activate this new version. 154 activeVersion, err := client.ActivateVersion(&fastly.ActivateVersionInput{ 155 ServiceID: serviceID, 156 ServiceVersion: version.Number, 157 }) 158 if err != nil { 159 log.Fatal(err) 160 } 161 162 // Output: true 163 fmt.Println("activeVersion.Locked:", activeVersion.Locked) 164 } 165 ``` 166 167 More information can be found in the 168 [Fastly Godoc][latest]. 169 170 ## Developing 171 172 1. Clone the project to your preferred directory, using your preferred method. 173 2. Download the module and accompanying developer tooling. 174 175 ```bash 176 $ go mod download 177 ``` 178 179 3. Make changes. 180 4. Verify those changes. 181 182 ```bash 183 $ make all 184 ``` 185 186 ## Testing 187 188 Go Fastly uses [go-vcr](https://github.com/dnaeon/go-vcr) to "record" and "replay" API request fixtures to improve the speed and portability of integration tests. The test suite uses a single test service ID for all test fixtures. 189 190 Contributors without access to the test service can still update the fixtures but with some additional steps required. Below is an example workflow for updating a set of fixture files (where `...` should be replaced with an appropriate value): 191 192 ```sh 193 # Remove all yaml fixture files from the specified directory. 194 # 195 rm -r fastly/fixtures/.../* 196 197 # Run a subsection of the tests. 198 # This will cause the deleted fixtures to be recreated. 199 # 200 # FASTLY_TEST_SERVICE_ID: should correspond to a real service you control. 201 # FASTLY_API_KEY: should be a real token associated with the Service you control. 202 # TESTARGS: allows you to use the -run flag of the 'go test' command. 203 # 204 make test FASTLY_TEST_SERVICE_ID="..." FASTLY_API_KEY="..." TESTARGS="-run=..." 205 ``` 206 207 > **NOTE**: to run the tests with go-vcr disabled, set `VCR_DISABLE=1` (`make test-full` does this). 208 209 When adding or updating client code and integration tests, contributors should record a new set of fixtures. Before submitting a pull request with new or updated fixtures, we ask that contributors update them to use the default service ID by running `make fix-fixtures` with `FASTLY_TEST_SERVICE_ID` set to the same value used to run your tests. 210 211 ```sh 212 make fix-fixtures FASTLY_TEST_SERVICE_ID="..." 213 ``` 214 215 ### Important Test Tips! 216 217 There are two important things external contributors need to do when running the tests: 218 219 1. Use a 'temporary' token for running the tests (only if regenerating the token fixtures). 220 2. Redact sensitive information in your fixtures. 221 222 You only need to use a temporary token when regenerating the 'token' fixtures. This is because there is a test to validate the _revoking_ of a token using the [`/tokens/self`](https://developer.fastly.com/reference/api/auth/#revoke-token-current) API endpoint, for which running this test (if there are no existing fixtures) will cause the token you provided at your command-line shell to be revoked/expired. So please don't use a token that's also used by a real/running application! Otherwise you'll discover those application may stop working as you've inadvertently caused your token to be revoked. 223 224 In general, any time you regenerate fixtures you should be sure to redact any sensitive information served back from the API, but specifically there is a test which _creates_ tokens that needs special attention: when regenerating the token fixtures this will require you to enter your actual account credentials (i.e. username/password) into the `token_test.go` file. You'll want to ensure that once the fixtures are created that you redact those values from both the generated fixture as well as the go test file itself. For example... 225 226 ```go 227 input := &CreateTokenInput{ 228 Name: "my-test-token", 229 Scope: "global", 230 Username: "XXXXXXXXXXXXXXXXXXXXXX", 231 Password: "XXXXXXXXXXXXXXXXXXXXXX", 232 } 233 ``` 234 235 ## Contributing 236 237 Refer to [CONTRIBUTING.md](./CONTRIBUTING.md) 238 239 ## License 240 241 ``` 242 Copyright 2015 Seth Vargo 243 244 Licensed under the Apache License, Version 2.0 (the "License"); 245 you may not use this file except in compliance with the License. 246 You may obtain a copy of the License at 247 248 http://www.apache.org/licenses/LICENSE-2.0 249 250 Unless required by applicable law or agreed to in writing, software 251 distributed under the License is distributed on an "AS IS" BASIS, 252 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 253 See the License for the specific language governing permissions and 254 limitations under the License. 255 ```