The Clerk Go SDK uses Semantic Versioning for tracking all changes to the library.
Semantic versions take the form of MAJOR.MINOR.PATCH
. Incrementing
- MAJOR version introduces incompatible API changes
- MINOR version introduces functionality in a backwards compatible manner
- PATCH version includes backwards compatible bug fixes
This file contains upgrade notes for all MAJOR
version bumps.
While there are no plans to sunset older versions of the Go SDK,
the current MAJOR
version of clerk-sdk-go
is actively supported.
Bug fixes and security updates may be added to previous versions, but there is no guarantee.
The v2
version of the Clerk Go SDK is a complete rewrite and introduces
a lot of breaking changes.
The minimum supported Go version for the v2
version of the Clerk Go SDK is 1.19
.
- client, err := clerk.NewClient("sk_live_XXX")
+ clerk.SetKey("sk_live_XXX")
- client.$Resource$().Create(clerk.Create$Resource$Params{})
+ $resource$.Create(ctx, $resource$.CreateParams{})
API operations in v1
of the Clerk Go SDK are organized by service. There are
different services for each API and all services are properties of a single
clerk.Client
.
In v2
API operations are grouped by API resource. Every API resource is defined in its own package.
// Create an organization, in v1 and v2. Error handling is omitted.
- client, err := clerk.NewClient("sk_live_XXX")
- org, err := client.Organizations().Create(clerk.CreateOrganizationParams{
- Name: "Acme Inc",
- })
+ ctx := context.Background()
+ clerk.SetKey("sk_live_XXX")
+ org, err := organization.Create(ctx, &organization.CreateParams{
+ Name: clerk.String("Acme Inc"),
+ })
All API operations in v2
receive a context.Context
as their first argument.
In v2
of the Clerk Go SDK, the return types of list operations are similar. They always contain the total count of resources
available in the server, and a slice with the operation results.
// Fetch a list of 10 users. Error handling is omitted.
- limit := 10
- users, err := client.Users().ListAll(clerk.ListAllUserParams{
- Limit: &limit,
- })
- if len(users) > 0 {
- fmt.Println(users[0].ID)
- }
+ params := &user.ListParams{}
+ params.Limit = clerk.Int64(10)
+ list, err := user.List(context.Background(), ¶ms)
+ if list.TotalLength > 0 {
+ fmt.Println(list.Users[0].ID)
+ }
The v2
version of the library introduces helper functions to generate pointers from various type values. These are:
clerk.String
clerk.Bool
clerk.Int64
clerk.JSONRawMessage
Using the helpers above, here's how you can invoke an API operation with a *Params
struct.
domain.Create(context.Background(), &domain.CreateParams{
Name: clerk.String("clerk.com"),
IsSatellite: clerk.Bool(true),
})
You can explicitly pass zero values with clerk.String("")
or clerk.Int64(0)
.
- clerk.ErrorResponse
+ clerk.APIErrorResponse
The v2
version of the library introduces a new type for API responses that contain errors.
The new type is clerk.APIErrorResponse and it replaces clerk.ErrorResponse
.
The clerk.APIErrorResponse
type contains additional fields and provides access to more debugging information.
- org, err := client.Organizations().Create(clerk.CreateOrganizationParams{
- Name: "Acme Inc",
- })
- if err != nil {
- if errResp, ok := err.(*clerk.ErrorResponse); ok {
- // Access the API errors
- errResp.Errors
- }
- }
+ ctx := context.Background()
+ clerk.SetKey("sk_live_XXX")
+ org, err := organization.Create(ctx, &organization.CreateParams{
+ Name: clerk.String("Acme Inc"),
+ })
+ if err != nil {
+ if apiErr, ok := err.(*clerk.APIErrorResponse); ok {
+ // Access the API errors and additional information
+ apiErr.TraceID
+ apiErr.Error()
+ apiErr.Response.RawJSON
+ }
+ }
- clerk.WithSessionV2
+ http.WithHeaderAuthorization
- clerk.RequireSessionV2
+ http.RequireHeaderAuthorization
- clerk.SessionFromContext
+ clerk.SessionClaimsFromContext
The clerk.WithSessionV2
and clerk.RequireSessionV2
middleware functions from v1
are replaced by http.WithHeaderAuthorization and http.RequireHeaderAuthorization in v2
Please note that as the name implies WithHeaderAuthorization
and RequireHeaderAuthorization
support only authentication with a bearer token.
The token needs to be provided in the "Authorization" request header.
[! IMPORTANT] Cookie based authentication is not supported at all by the
v2
version of the library.
To get access to the active session claims from the http.Request context, you must replace clerk.SessionFromContext
with clerk.SessionClaimsFromContext.
// Protect a route with Clerk authentication middleware.
// Error handling is omitted.
mux := http.NewServeMux()
- client, err := clerk.NewClient("sk_live_XXX")
- mux.Handle("/session", clerk.RequireSessionV2(client)(http.HandlerFunc(handleSession)))
+ clerk.SetKey("sk_live_XXX")
+ mux.Handle("/session", clerkhttp.RequireHeaderAuthorization()(http.HandlerFunc(handleSession)))
http.ListenAndServe(":3000", mux)
func handleSession(w http.ResponseWriter, r *http.Request) {
- sessionClaims, ok := clerk.SessionFromContext(r.Context())
+ sessionClaims, ok := clerk.SessionClaimsFromContext(r.Context())
if ok {
// claims contain session information
} else {
// there is no active session (non-authenticated user)
}
}
All available middleware options are preserved in the v2
version of the library, but they have been renamed.
- WithAuthorizedParty(...string)
+ AuthorizedPartyMatches(...string)
- WithLeeway(time.Duration)
+ Leeway(time.Duration)
- WithJWTVerificationKey(string)
+ JSONWebKey(string)
- WithSatelliteDomain(string)
+ Satellite(string)
- WithProxyURL(string)
+ ProxyURL(string)
- WithCustomClaims(interface{})
+ CustomClaimsConstructor(func(context.Context) any)
The v2
version of the Clerk Go SDK provides additional middleware options.
The clerk.VerifyToken
method in version v1
of the Clerk Go SDK has been renamed to jwt.Verify in v2
.
The method accepts the same parameters, with two important differences.
- You can provide the JSON web key with which the token will be verified.
- If you don't provide the JSON web key, you can provide a jwks.Client that will be used to retrieve it. If you don't provide a jwks.Client, one with default configuration will be used.
- The method will not cache the JSON web key.
sessionToken := "the-clerk-session-jwt"
- client := clerk.NewClient("sk_live_XXXX")
- claims, err := client.VerifyToken(sessionToken)
+ claims, err := jwt.Verify(context.Background(), &jwt.VerifyParams{
+ Token: sessionToken,
+ })