Skip to content
This repository was archived by the owner on Jul 2, 2025. It is now read-only.

Commit 2dd5fef

Browse files
authored
Add API version header (#29)
1 parent 1158294 commit 2dd5fef

File tree

6 files changed

+48
-8
lines changed

6 files changed

+48
-8
lines changed

adminapi/adminapi.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ type Error = types.UserHubError
1717
// New returns a new Admin API client.
1818
func New(adminKey string, opts ...option.ClientOption) (Client, error) {
1919
o := &options.ClientOptions{
20-
BaseUrl: internal.ApiBaseUrl,
21-
Headers: http.Header{},
20+
ApiVersion: internal.ApiVersion,
21+
BaseUrl: internal.ApiBaseUrl,
22+
Headers: http.Header{},
2223
}
2324
for _, opt := range opts {
2425
if opt != nil {
@@ -29,6 +30,8 @@ func New(adminKey string, opts ...option.ClientOption) (Client, error) {
2930
return nil, err
3031
}
3132

33+
o.Headers.Set(internal.ApiVersionHeader, o.ApiVersion)
34+
3235
adminKey = strings.TrimSpace(adminKey)
3336
if adminKey == "" {
3437
return nil, internal.CallErrorf(nil, nil, "adminKey required")

basics_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/userhubdev/go-sdk/adminapi"
1616
"github.com/userhubdev/go-sdk/adminv1"
1717
"github.com/userhubdev/go-sdk/code"
18+
"github.com/userhubdev/go-sdk/internal"
1819
"github.com/userhubdev/go-sdk/option"
1920
"github.com/userhubdev/go-sdk/userapi"
2021
)
@@ -86,7 +87,9 @@ func TestApiGet(t *testing.T) {
8687
t.Parallel()
8788

8889
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
90+
require.Equal(t, internal.ApiVersion, r.Header.Get("userhub-api-version"))
8991
require.Equal(t, "Bearer sk_test", r.Header.Get("authorization"))
92+
require.Equal(t, internal.UserAgent, r.Header.Get("user-agent"))
9093
require.Equal(t, "/admin/v1/users/usr_1", r.URL.Path)
9194
require.Equal(t, "GET", r.Method)
9295
_, _ = w.Write([]byte(`{"id": "usr_1", "displayName": "Jane Doe"}`))
@@ -107,7 +110,9 @@ func TestApiPost(t *testing.T) {
107110
t.Parallel()
108111

109112
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
113+
require.Equal(t, internal.ApiVersion, r.Header.Get("userhub-api-version"))
110114
require.Equal(t, "Bearer sk_test", r.Header.Get("authorization"))
115+
require.Equal(t, internal.UserAgent, r.Header.Get("user-agent"))
111116
require.Equal(t, "/admin/v1/users", r.URL.Path)
112117
require.Equal(t, "POST", r.Method)
113118

@@ -139,7 +144,9 @@ func TestApiPost_Empty(t *testing.T) {
139144
t.Parallel()
140145

141146
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
147+
require.Equal(t, internal.ApiVersion, r.Header.Get("userhub-api-version"))
142148
require.Equal(t, "Bearer sk_test", r.Header.Get("authorization"))
149+
require.Equal(t, internal.UserAgent, r.Header.Get("user-agent"))
143150
require.Equal(t, "/admin/v1/users", r.URL.Path)
144151
require.Equal(t, "POST", r.Method)
145152

@@ -169,7 +176,9 @@ func TestApiPatch(t *testing.T) {
169176
t.Parallel()
170177

171178
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
179+
require.Equal(t, internal.ApiVersion, r.Header.Get("userhub-api-version"))
172180
require.Equal(t, "Bearer sk_test", r.Header.Get("authorization"))
181+
require.Equal(t, internal.UserAgent, r.Header.Get("user-agent"))
173182
require.Equal(t, "/admin/v1/users/usr_1", r.URL.Path)
174183
require.Equal(t, "PATCH", r.Method)
175184

@@ -201,7 +210,9 @@ func TestApiPatch_Empty(t *testing.T) {
201210
t.Parallel()
202211

203212
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
213+
require.Equal(t, internal.ApiVersion, r.Header.Get("userhub-api-version"))
204214
require.Equal(t, "Bearer sk_test", r.Header.Get("authorization"))
215+
require.Equal(t, internal.UserAgent, r.Header.Get("user-agent"))
205216
require.Equal(t, "/admin/v1/users/usr_1", r.URL.Path)
206217
require.Equal(t, "PATCH", r.Method)
207218

@@ -233,7 +244,9 @@ func TestApiDelete(t *testing.T) {
233244
t.Parallel()
234245

235246
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
247+
require.Equal(t, internal.ApiVersion, r.Header.Get("userhub-api-version"))
236248
require.Equal(t, "Bearer sk_test", r.Header.Get("authorization"))
249+
require.Equal(t, internal.UserAgent, r.Header.Get("user-agent"))
237250
require.Equal(t, "/admin/v1/users/usr_1", r.URL.Path)
238251
require.Equal(t, "DELETE", r.Method)
239252
_, _ = w.Write([]byte(`{"id": "usr_1"}`))

internal/constants.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ import (
88

99
const (
1010
ApiBaseUrl = "https://api.userhub.com"
11+
ApiVersion = "2022-11-15"
1112
UserAgent = "UserHub-Go/0.7.0"
1213
Version = "0.7.0"
1314

14-
AuthHeader = "Authorization"
15-
ApiKeyHeader = "UserHub-Api-Key"
15+
AuthHeader = "Authorization"
16+
ApiKeyHeader = "UserHub-Api-Key"
17+
ApiVersionHeader = "UserHub-Api-Version"
1618

1719
WebhookActionHeader = "UserHub-Action"
1820
WebhookAgentHeader = "Webhook-Agent"

internal/options/options.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,22 @@ import (
1111
)
1212

1313
type ClientOptions struct {
14-
BaseUrl string
15-
Headers http.Header
14+
ApiVersion string
15+
BaseUrl string
16+
Headers http.Header
1617
}
1718

1819
func (o *ClientOptions) Validate() error {
1920
if o == nil {
2021
return errors.New("userhub: client options required")
2122
}
2223

24+
if o.ApiVersion == "" {
25+
return errors.New("userhub: API version required")
26+
} else if len(o.ApiVersion) != 10 {
27+
return errors.New("userhub: API version is invalid (e.g. 2022-11-15)")
28+
}
29+
2330
if o.BaseUrl == "" {
2431
return errors.New("userhub: base URL required")
2532
} else if o.BaseUrl != internal.ApiBaseUrl {

option/client.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,15 @@ func (w withBaseUrl) Apply(options *options.ClientOptions) {
1919
options.BaseUrl = w.baseUrl
2020
}
2121
}
22+
23+
func WithApiVersion(apiVersion string) ClientOption {
24+
return withApiVersion{apiVersion: apiVersion}
25+
}
26+
27+
type withApiVersion struct{ apiVersion string }
28+
29+
func (w withApiVersion) Apply(options *options.ClientOptions) {
30+
if w.apiVersion != "" {
31+
options.ApiVersion = w.apiVersion
32+
}
33+
}

userapi/userapi.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ type Error = types.UserHubError
1717
// New returns a new User API client.
1818
func New(userKey, accessToken string, opts ...option.ClientOption) (Client, error) {
1919
o := &options.ClientOptions{
20-
BaseUrl: internal.ApiBaseUrl,
21-
Headers: http.Header{},
20+
ApiVersion: internal.ApiVersion,
21+
BaseUrl: internal.ApiBaseUrl,
22+
Headers: http.Header{},
2223
}
2324
for _, opt := range opts {
2425
if opt != nil {
@@ -29,6 +30,8 @@ func New(userKey, accessToken string, opts ...option.ClientOption) (Client, erro
2930
return nil, err
3031
}
3132

33+
o.Headers.Set(internal.ApiVersionHeader, o.ApiVersion)
34+
3235
userKey = strings.TrimSpace(userKey)
3336
if userKey == "" {
3437
return nil, internal.CallErrorf(nil, nil, "userKey required")

0 commit comments

Comments
 (0)