-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathclient.go
120 lines (111 loc) · 3.11 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// package control is an implementation of the Ably Control API.
//
// The Ably Control API is a REST API that enables you to manage your Ably
// account programmatically https://ably.com/documentation/control-api.
//
// Using the Control API you can automate the provisioning, management,
// and testing of your Ably realtime infrastructure. You can dynamically
// create Ably apps, configure them, and delete them if necessary.
//
// With the Control API you can create and manage:
// - Your Ably apps
// - API keys for an Ably app
// - Namespaces (for channel rules)
// - Queues
// - Integration rules
//
// Control API is currently in Preview.
package control
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
// The URL of the Ably Control API.
const API_URL = "https://control.ably.net/v1"
// defaultAblyAgent is the default value to set as the Ably-Agent HTTP header,
// and can be extended for an individual Client by calling the AppendAblyAgent
// method.
const defaultAblyAgent = "ably-control-go/" + VERSION
// Client represents a REST client for the Ably Control API.
type Client struct {
token string
accountID string
// Url is the base url for the REST API.
Url string
/// ablyAgent is the value to set as the Ably-Agent HTTP header.
ablyAgent string
}
// NewClient creates a new REST client.
//
// Creating a new client involves making a request to the REST API to
// fetch the account ID accociated with the token.
func NewClient(token string) (Client, Me, error) {
return NewClientWithURL(token, API_URL)
}
// / NewClientWithURL is the same as NewClient but also takes a custom url.
func NewClientWithURL(token, url string) (Client, Me, error) {
client := Client{
token: token,
Url: url,
ablyAgent: defaultAblyAgent,
}
me, err := client.Me()
if err != nil {
return client, me, err
}
client.accountID = me.Account.ID
return client, me, nil
}
// AppendAblyAgent appends an extra entry to the value sent as the Ably-Agent
// HTTP header.
func (c *Client) AppendAblyAgent(product, version string) {
c.ablyAgent = fmt.Sprintf("%s %s/%s", c.ablyAgent, product, version)
}
func (c *Client) request(method, path string, in, out interface{}) error {
var inR io.Reader
if in != nil {
inData, err := json.Marshal(in)
if err != nil {
return err
}
inR = bytes.NewReader(inData)
}
req, err := http.NewRequest(method, c.Url+path, inR)
if err != nil {
return err
}
req.Header.Set("Authorization", "Bearer "+c.token)
req.Header.Set("Ably-Agent", c.ablyAgent)
if in != nil {
req.Header.Set("Content-Type", "application/json")
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
if res.StatusCode < 200 || res.StatusCode >= 300 {
body, _ := io.ReadAll(res.Body)
var errorInfo ErrorInfo
err = json.Unmarshal(body, &errorInfo)
if err == nil {
errorInfo.APIPath = path
return errorInfo
} else {
return ErrorInfo{
Message: string(body),
Code: 0,
StatusCode: res.StatusCode,
HRef: "",
APIPath: path,
}
}
}
if out != nil {
return json.NewDecoder(res.Body).Decode(out)
}
return nil
}