Skip to content

Commit c6d934d

Browse files
authored
Chore/improve readme (#301)
1 parent 773184b commit c6d934d

File tree

2 files changed

+110
-88
lines changed

2 files changed

+110
-88
lines changed

DEVELOPING.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Developing
2+
3+
If you spot an issue, or have an idea for a feature that would make your work with this SDK easier - don't hesitate to open an issue or make a pull requests. We are grateful for all feedback and contributions.
4+
5+
## Code style & linting
6+
7+
We use [golangci-lint](https://github.com/golangci/golangci-lint) for linting and formatting. Please run `golangci-lint run ./...` before making a PR.
8+
9+
## Commit Messages
10+
11+
Please follow [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/).
12+
13+
## Testing
14+
15+
To be able to run the test suite you'll need to export the following environment variables with their corresponding
16+
values:
17+
18+
* `UPCLOUD_GO_SDK_TEST_USER` (the API username)
19+
* `UPCLOUD_GO_SDK_TEST_PASSWORD` (the API password)
20+
* `UPCLOUD_GO_SDK_TEST_DELETE_RESOURCES` (either `yes` or `no`)
21+
22+
To run the test suite, run `go test ./... -v -parallel 8`. If `UPCLOUD_GO_SDK_TEST_DELETE_RESOURCES` is set to `yes`,
23+
all resources will be stopped and/or deleted after the test suite has run. Be careful which account you use for
24+
testing so you don't accidentally delete or your production resources!
25+
26+
You can skip running the integration tests and just run the unit tests by passing `-short` to the test command.
27+
28+
## Debugging
29+
30+
Environment variables `UPCLOUD_DEBUG_API_BASE_URL` and `UPCLOUD_DEBUG_SKIP_CERTIFICATE_VERIFY` can be used for HTTP client debugging purposes.
31+
* `UPCLOUD_DEBUG_API_BASE_URL` overrides static base URL. This can be used with local server to debug request problems.
32+
E.g. `UPCLOUD_DEBUG_API_BASE_URL=http://127.0.0.1:8080`
33+
* `UPCLOUD_DEBUG_SKIP_CERTIFICATE_VERIFY` skips server's certificate verification. If set to `1`, API client accepts any certificate presented by the server and any host name in that certificate.
34+
E.g. `UPCLOUD_DEBUG_SKIP_CERTIFICATE_VERIFY=1`

README.md

Lines changed: 76 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -6,92 +6,103 @@
66

77
This is the official client for interfacing with UpCloud's API using the Go programming language. The features allows for easy and quick development and integration when using Go.
88

9-
## Installation and requirements
10-
11-
You'll need Go 1.18 or higher to use the client. You can use the following command to retrieve the client:
12-
13-
```
14-
go get github.com/UpCloudLtd/upcloud-go-api
15-
```
16-
179
## Usage
1810

19-
The general usage of the client adheres to the following pattern:
20-
21-
* Authenticate by creating a `client.Client`
22-
* Create a `service.Service` by passing the newly created `client` object to it
23-
* Interface with the API using the various methods of the `service` object. Methods that take parameters wrap them in request objects.
24-
25-
We recommend setting up a separate subaccount for API usage to allow better access control and security. You can find out more about creating subaccounts at the following support article for [Server Tags and Group Accounts](https://www.upcloud.com/support/server-tags-and-group-accounts/). We strongly recommend limiting the connections to a specific address or address range for security purposes.
11+
### Quickstart
2612

27-
The examples here only deal with how to use the client itself. For information on how to use the API in general, please consult the [UpCloud API documentation](https://www.upcloud.com/api/).
28-
29-
### Creating the client and the service
30-
31-
```go
32-
// Authenticate by passing your account login credentials to the client
33-
c := client.New(user, password)
34-
35-
// It is generally a good idea to override the default timeout of the underlying HTTP client since some requests block for longer periods of time
36-
c.SetTimeout(time.Second * 30)
37-
38-
// Create the service object
39-
svc := service.New(c)
13+
Add SDK to your project. You will need Go 1.20+ to use it.
14+
```shell
15+
go get github.com/UpCloudLtd/upcloud-go-api/v8
4016
```
41-
### Validating credentials
42-
43-
The easiest way to check whether the client credentials are correct is to issue a call to `GetAccount()`.
4417

18+
Next in your code:
4519
```go
46-
username := "completely"
47-
password := "invalid"
20+
import (
21+
"time"
4822

49-
svc := service.New(client.New(username, password))
23+
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud/client"
24+
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud/service"
25+
)
5026

51-
_, err := svc.GetAccount(context.Background())
27+
func main() {
28+
// First instantiate a client with your username and password.
29+
// `client.New` accepts config functions that allow you to customise the returned client behaviour.
30+
// Config functions are exported from the `client` package.
31+
clnt := client.New("my_username", "password123", client.WithTimeout(time.Second * 30))
5232

53-
if err != nil {
54-
panic("Invalid credentials")
33+
// Next instantiate new service using the created client
34+
svc := service.New(clnt)
35+
36+
// Validate that everything is set up correctly
37+
account, err := svc.GetAccount(context.Background())
5538
}
5639
```
5740

5841
### Error handling
5942

60-
All `Service` methods return a result and an error object. You can differentiate between generic connection errors (like the API not being reachable) and service errors, which are errors returned in the response body by the API. This is useful for gracefully recovering from certain types of errors.
61-
6243
```go
63-
username := "completely"
64-
password := "invalid"
65-
66-
svc := service.New(client.New(username, password))
67-
68-
_, err := svc.GetAccount(context.Background())
69-
70-
// Handle errors in general
71-
if (err != nil) {
72-
// Handle service errors specifically
73-
if serviceError, ok := err.(*upcloud.Problem); ok {
74-
fmt.Println(serviceError.Type)
75-
fmt.Println(serviceError.Title)
76-
fmt.Prinln(serviceError.Status)
77-
// You can use ErrorCode() method to compare error against a set of ErrCode constants
78-
if serviceError.ErrorCode == upcloud.ErrCodeAuthenticationFailed {
79-
// ...
44+
import (
45+
"context"
46+
"errors"
47+
"fmt"
48+
49+
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud"
50+
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud/client"
51+
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud/service"
52+
)
53+
54+
func main() {
55+
svc := service.New(client.New("my_username", "password123"))
56+
_, err := svc.GetAccount(context.Background())
57+
58+
if err != nil {
59+
// `upcloud.Problem` is the error object returned by all of the `Service` methods.
60+
// You can differentiate between generic connection errors (like the API not being reachable) and service errors, which are errors returned in the response body by the API;
61+
// this is useful for gracefully recovering from certain types of errors;
62+
var problem *upcloud.Problem
63+
64+
if errors.As(err, &problem) {
65+
fmt.Println(problem.Status) // HTTP status code returned by the API
66+
fmt.Print(problem.Title) // Short, human-readable description of the problem
67+
fmt.Println(problem.CorrelationID) // Unique string that identifies the request that caused the problem; note that this field is not always populated
68+
fmt.Println(problem.InvalidParams) // List of invalid request parameters
69+
70+
for _, invalidParam := range problem.InvalidParams {
71+
fmt.Println(invalidParam.Name) // Path to the request field that is invalid
72+
fmt.Println(invalidParam.Reason) // Human-readable description of the problem with that particular field
73+
}
74+
75+
// You can also check against the specific api error codes to programatically react to certain situations.
76+
// Base `upcloud` package exports all the error codes that API can return.
77+
// You can check which error code is return in which situation in UpCloud API docs -> https://developers.upcloud.com/1.3
78+
if problem.ErrorCode() == upcloud.ErrCodeResourceAlreadyExists {
79+
fmt.Println("Looks like we don't need to create this")
80+
}
81+
82+
// `upcloud.Problem` implements the Error interface, so you can also just use it as any other error
83+
fmt.Println(fmt.Errorf("we got an error from the UpCloud API: %w", problem))
84+
} else {
85+
// This means you got an error, but it does not come from the API itself. This can happen, for example, if you have some connection issues,
86+
// or if the UpCloud API is unreachable for some other reason
87+
fmt.Println("We got a generic error!")
8088
}
8189
}
8290
}
83-
````
91+
```
8492

85-
This snippet would print the following:
93+
### Packages
8694

87-
```
88-
AUTHENTICATION_FAILED
89-
Authentication failed using the given username and password.
90-
```
95+
UpCloud Go SDK includes the following packages:
96+
- `upcloud` package - contains type definitions for all UpCloud API objects like servers, storages, load balancers, Kubernetes clusters, errors, etc. It also has a lot of constants that allow you, for example, to compare state, status and other properties of various objects.
97+
- `client` package - contains functions that allow you to create and customise HTTP client that will be used to make requests to UpCloud API. The returned client does expose some methods for making requests, but you shouldn't really use them directly, client should only be used to instantiate a new `Service`
98+
- `service` package - contains the `Service` type, which exposes all the methods to interact with UpCloud API. This is the package you will probably use most frequently. All `Service` methods accept `context.Context` as firt parameter. _Most_ `Service` methods accept a `request` object as the second parameter (see package below).
99+
- `request` package - contains various `request` objects. Those objects should always be used as an argument for a `Service` method and allow you to provide additional params for the request URL or body. For example, when fetching details of a speficic server, you would use a request object to speficy the server UUID. Similarly, when creating server you would use request object to specify server properties, like CPU, memory, OS, login method, etc.
100+
101+
### Examples
91102

92-
The rest of these examples assume you already have a service object configured and named `svc`.
103+
All of these examples assume you already have a service object configured and named `svc`.
93104

94-
### Retrieving a list of servers
105+
#### Retrieving a list of servers
95106

96107
The following example will retrieve a list of servers the account has access to.
97108

@@ -109,7 +120,7 @@ for _, server := range servers.Servers {
109120
}
110121
```
111122

112-
### Creating a new server
123+
#### Creating a new server
113124

114125
Since the request for creating a new server is asynchronous, the server will report its status as "maintenance" until the deployment has been fully completed.
115126

@@ -230,29 +241,6 @@ if err != nil {
230241

231242
For more examples, please consult the service integration test suite (`upcloud/service/service_test.go`).
232243

233-
## Testing
234-
235-
To be able to run the test suite you'll need to export the following environment variables with their corresponding
236-
values:
237-
238-
* `UPCLOUD_GO_SDK_TEST_USER` (the API username)
239-
* `UPCLOUD_GO_SDK_TEST_PASSWORD` (the API password)
240-
* `UPCLOUD_GO_SDK_TEST_DELETE_RESOURCES` (either `yes` or `no`)
241-
242-
To run the test suite, run `go test ./... -v -parallel 8`. If `UPCLOUD_GO_SDK_TEST_DELETE_RESOURCES` is set to `yes`,
243-
all resources will be stopped and/or deleted after the test suite has run. Be careful which account you use for
244-
testing so you don't accidentally delete or your production resources!
245-
246-
You can skip running the integration tests and just run the unit tests by passing `-short` to the test command.
247-
248-
## Debugging
249-
250-
Environment variables `UPCLOUD_DEBUG_API_BASE_URL` and `UPCLOUD_DEBUG_SKIP_CERTIFICATE_VERIFY` can be used for HTTP client debugging purposes.
251-
* `UPCLOUD_DEBUG_API_BASE_URL` overrides static base URL. This can be used with local server to debug request problems.
252-
E.g. `UPCLOUD_DEBUG_API_BASE_URL=http://127.0.0.1:8080`
253-
* `UPCLOUD_DEBUG_SKIP_CERTIFICATE_VERIFY` skips server's certificate verification. If set to `1`, API client accepts any certificate presented by the server and any host name in that certificate.
254-
E.g. `UPCLOUD_DEBUG_SKIP_CERTIFICATE_VERIFY=1`
255-
256244
## License
257245

258246
This client is distributed under the [MIT License](https://opensource.org/licenses/MIT), see LICENSE.txt for more information.

0 commit comments

Comments
 (0)