Skip to content

AccelByte/accelbyte-go-modular-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AccelByte Modular Go SDK

⚠️ This accelbyte-go-modular-sdk is not to be confused with accelbyte-go-sdk:

  • The former (modular SDK) is experimental and is planned to be the sucessor for the latter (monolithic SDK).
  • The modular SDK allows developers to include only the required modules in projects.
  • If you are starting a new project, you try to use modular SDK.
  • If you use monolithic SDK in an existing project, a migration path is available via compatibility layer in modular SDK.
  • Both monolithic and modular SDK will be maintained for some time to give time for migration until monolithic SDK is deprecated in the future.

A software development kit (SDK) for interacting with AccelByte Gaming Services (AGS) written in Go.

This SDK was generated from AGS OpenAPI spec files included in the spec directory.

Setup

This SDK requires go 1.18 or newer version to be installed.

Import SDK Project

For example, add the following to your project's go.mod:

Instead of

require (
    github.com/AccelByte/accelbyte-go-sdk {VERSION}
)

Migrate with

require (
    github.com/AccelByte/accelbyte-go-modular-sdk/{service}-sdk {VERSION}
)

Instead of importing the whole package, select which AGS service we want to import in the project. Use more than one AGS service if necessary.

Replace {VERSION} with a specific release version tag. When starting a new project, using the latest release version is recommended.

For more example, please refer to the samples folder.

NOTE: Here is the exhaustive list of go sdk modules available to be used - Published Go Modules

Environment Variables

The following environment variables need to be set when using ConfigRepository.

Name Required Example
AB_BASE_URL Yes https://test.accelbyte.io
AB_CLIENT_ID Yes abcdef0123456789abcdef0123456789
AB_CLIENT_SECRET Yes, but only if you use a confidential AB_CLIENT_ID ab#c,d)ef(ab#c,d)ef(ab#c,d)ef(ab

Migrating An Existing Project

To start migrating an existing project which uses accelbyte-go-sdk monolithic package to this accelbyte-go-modular-sdk modular package, it can be done with minimum effort by importing the AGS service of choice in the go.mod files and use go build -tags compat to build it with compatibility layer. After this, the compatibility layer can be removed bit by bit until the project is fully migrated.

Usage

Instantiation

// example for OAuth20 in IAM service
oAuth20Service := iam.OAuth20Service{
    Client:           factory.NewIamClient(auth.DefaultConfigRepositoryImpl()), 
    ConfigRepository: auth.DefaultConfigRepositoryImpl(), 
    TokenRepository:  auth.DefaultTokenRepositoryImpl(),
}

Enable HTTP Logging

To enable http logging feature, set ENABLE_LOG to true in the environment variables.

export ENABLE_LOG=true

With Custom HTTP retry in the client

Use this to get SDK instance with HTTP retry functionality.

input := &o_auth2_0.TokenGrantV3Params{
		Password:  &password,
		Username:  &username,
		GrantType: o_auth2_0.TokenGrantV3PasswordConstant,
	}
input.RetryPolicy = &utils.Retry{
    Transport: OAuth20Service.Client.Runtime.Transport,
    MaxTries:  utils.MaxTries,
    Backoff:   utils.NewConstantBackoff(0),
    RetryCodes: map[int]bool{
        502: true, // add an error code for bad gateway
    },
}
ok, err := OAuth20Service.TokenGrantV3Short(input) // call the wrapper

Automatic Token Refresh

The Automatic Token Refresh is invoked by auth.RefreshTokenScheduler inside the login wrapper with the Default configuration and can be override. Use the following to get SDK instance with automatic token refresh functionality which is performed before each HTTP request but only if access token is almost expired.

oAuth20Service = &iam.OAuth20Service{
		Client:           factory.NewIamClient(auth.DefaultConfigRepositoryImpl()),
		ConfigRepository: auth.DefaultConfigRepositoryImpl(),
		TokenRepository:  auth.DefaultTokenRepositoryImpl(),
		RefreshTokenRepository: &auth.RefreshTokenImpl{ // override the default refresh token. For example, enable the AutoRefresh functionality or change RefreshRate
			RefreshRate: 0.5,
			AutoRefresh: true,
		},
	}

Use the repository to access all functions for refresh token.

On-demand Refresh Token

The on-demand refresh token is intended to be used in environment where automatic refresh token cannot work properly e.g. AWS Lambda. The way to initialize it is similar to automatic refresh token except the AutoRefresh parameter must be set to false. After that, LoginOrRefreshClient or LoginOrRefresh for logging in using client token or username and password respectively can be used before calling any endpoints. These two functions are helper functions for developers to either login or refresh as required.

oAuth20Service = &iam.OAuth20Service{
    Client:           factory.NewIamClient(auth.DefaultConfigRepositoryImpl()),
    ConfigRepository: auth.DefaultConfigRepositoryImpl(),
    TokenRepository:  auth.DefaultTokenRepositoryImpl(),
    RefreshTokenRepository: &auth.RefreshTokenImpl{
        RefreshRate: 0.5,
        AutoRefresh: false, // must be set to false for on demand refresh token
    },
}
...
err := oauth.LoginOrRefreshClient("clientId", "clientSecret")   // use before calling endpoints, using client token
...
err := oauth.LoginOrRefresh("username", "password")     // use before calling endpoints, using username and password

Working example code for on-demand refresh token is available in ondemand-refresh-token.

Local Token Validation

Local token validation is available since version 0.37.0. To enable it, import the package

import (
    ...
    "github.com/AccelByte/accelbyte-go-modular-sdk/services-api/pkg/utils/auth/validator"
    ...
)

configure authTokenValidator struct or use the existing one NewTokenValidator with the default localValidationActive is false. Invoked them with

tokenValidator := validator.NewTokenValidator(authService, time.Hour)
tokenValidator.Initialize()

err = tokenValidator.Validate(accessToken, &requiredPermission, &namespace, nil)

if want to set localValidationActive is true, use a TokenValidator directly and do this:

tokenValidator := &validator.TokenValidator{
		AuthService:     *oAuth20Service,
		RefreshInterval: time.Hour,

		Filter:                nil,
		JwkSet:                nil,
		JwtClaims:             validator.JWTClaims{},
		JwtEncoding:           *base64.URLEncoding.WithPadding(base64.NoPadding),
		PublicKeys:            make(map[string]*rsa.PublicKey),
		LocalValidationActive: true, // set here to true
		RevokedUsers:          make(map[string]time.Time),
		Roles:                 make(map[string]*iamclientmodels.ModelRoleResponseV3),
	}
	
tokenValidator.Initialize()

err = tokenValidator.Validate(accessToken, &requiredPermission, &namespace, nil)

Login

Login Using Username and Password

err := oAuth20Service.Login(username, password)
if err != nil {
    return err
}

You can also specify the scope you want for LoginWithScope(...). With the scope parameter typed as string. By default the scope used is commerce account social publishing analytics (a space separated value string).

err := oAuth20Service.LoginWithScope(username, password, scope)
if err != nil {
    return err
}

Login Using OAuth Client (Public or Private)

err := oAuth20Service.GrantTokenCredentials("", "")
if err != nil {
    return err
}

💡 The use of a Public OAuth Client is highly discouraged! Please ensure that you both set the Client ID and Client Secret.

Parse Access Token

Functionality to parse the access token is available in v0.50.0. The function exist alongside the Login functionality in OAuth20Service. To use it, import the package

import (
    ...
    "github.com/AccelByte/accelbyte-go-modular-sdk/services-api/pkg/service/iam"
    ...
)

Get the token, and use ParseAccessToken function. Set the second parameter as true if it wants to validate before parse the access token

// get the access token string
accessToken, err := oAuth20Service.GetToken()
if err != nil {
    // fail here
}

// parse the token
parsedToken, err := oAuth20Service.ParseAccessToken(accessToken, true) // set true here to validate before parse the access token
if err != nil {
    // fail here
}
  • if the boolean is false, it will not validate the token at all.
  • if the boolean is true, it will validate remotely (call VerifyTokenV3 endpoint).
  • if the boolean is true and call SetLocalValidation before ParseAccessToken, it will validate locally.
oAuth20Service.SetLocalValidation(true) // call this also to activate local validation

// parse the token
parsedToken, err := oAuth20Service.ParseAccessToken(accessToken, true) // set true here to validate before parsing the access token
if err != nil {
// fail here
}

Interacting with AccelByte Gaming Services HTTP Endpoints

As an example, we will get current user profile info using getMyProfileInfo endpoint available in basic service.

// Instantiate UserProfile (Basic service) and input model as the global variable
var (
    userProfileService = &basic.UserProfileService{
        Client:          factory.NewBasicClient(auth.DefaultConfigRepositoryImpl()), 
        TokenRepository: auth.DefaultTokenRepositoryImpl(),
    }
    input = &user_profile.GetUserProfileInfoParams{
        Namespace: namespace,
    }
)

// Login using username and password
err := oAuth20Service.Login(username, password)
if err != nil {
    return err
}

// Make a call to getMyProfileInfo endpoint through the wrapper
ok, err := userProfileService.GetMyProfileInfoShort(input)
if err != nil {
    return err
}

The basic-sdk contains 2 directories:

  • basicclient contains the logic to make requests.
  • basicclientmodels contains the models such as request and response models.

Client must create a struct that implement following interface:

  • ConfigRepository is responsible to store configuration.
  • TokenRepository is responsible to store access token.

For more details, see repository for the interface and cli samples on how to use it.

Interacting with AccelByte Gaming Services WebSocket Endpoints

To interact with AccelByte Gaming Services services which use WebSocket endpoints e.g. AccelByte Gaming Services Lobby Service, use an existing Initialisation code or implement custom connectionutils/ConnectionManager interface. ConnectionManager manages WebSocket connection that save, get and close the WebSocket connection. In other words, client should maintain WebSocket connection using ConnectionManager.

connMgr = &integration.ConnectionManagerImpl{}
conn, err := connectionutils.NewWSConnection(
oAuth20Service.ConfigRepository, oAuth20Service.TokenRepository,
connectionutils.WithEnableAutoReconnect(), connectionutils.WithMessageHandler(lobbyMessageHandler), // do optionals
)
if err != nil {
// error
}
lobbyClient := connectionutils.NewLobbyWebSocketClient(conn)

// [optional] do something before Connecting

success, err := lobbyClient.Connect(false) // Connecting
if err != nil {
// error
}

connMgr.Save(conn)

// CASE Lobby get a notification
err = notificationService.GetNotificationMessage()
// error

For reference, see connectionutils_test.go or samples/cli/pkg/utils/connectionManager.go.

Refresh Token

getToken, errGetToken := oAuth20Service.TokenRepository.GetToken()
    if errGetToken != nil {
        // failed to get token
    }
	
hasExpired := repository.HasTokenExpired(*getToken) // use the repository of the sdk to get the available functions

Logout

err := oAuth20Service.Logout()
if err != nil {
    return err
}

FlightID

Since ags/v3.67.0, Go Extend SDK enable support for FlightID transmission during Http request. By default, new flight id will be generated when the sdk is loaded. There will be some case that this default value need to be updated with new value.

  • To update default flight id globally, use following code:

    utils.GetDefaultFlightID().SetFlightID("<new flight id value>");

    This will update the default flight id, and will be used by newly created sdk object (this example use " userProfileService").

    or

    userProfileService.FlightIdRepository = &utils.FlightIdContainer{Value: "<new flight id value>"}

    This will update the default flight id, and will be used by newly created sdk object (won't affect existing sdk object created before this code get executed).

  • To update flight id value in sdk object, use following code:

    userProfileService.UpdateFlightId("<new flight id value>")

    This will update the flight id value stored inside the sdk object. Will be used for all operations executed by the sdk object.

  • To update flight id value for specific operation, use UpdateFlightId parameter when building the operation object.

    // Make a call to GetMyProfileInfo endpoint
    input := &user_profile.GetMyProfileInfoParams{
        Namespace: admin,
    }
    input.XFlightId = "<new flight id value>"
    ok, err := userProfileService.GetMyProfileInfoShort(input)

Samples

Sample apps are available in the samples directory.

Documentation

Reference about AccelByte service endpoints and their corresponding SDK API is available in docs/operations directory.

Sample app documentations are available in the docs/samples directory.

For more information on how to use AccelByte services and SDKs, see docs.accelbyte.io.