client

package
v0.0.1-alpha.0...-700cb3a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 16, 2021 License: MIT Imports: 17 Imported by: 0

README

Client

Wraps http.Client and session state, provides configuration and ratelimiting logic.

Authentication

Making authenticated requests to the Salesforce REST API requires appending an Authorization header with a valid oauth2 access token. Of the available methods for generating an access code we support the OAuth 2.0 JWT Bearer Flow for Server-to-Server Integration and the OAuth 2.0 Username-Password Flow for Special Scenarios.

Usage

Both the client.Client object and its underlying http.Client use the functional-option pattern for configuration.

client, err := client.New(
    client.WithLoginFailover(
        client.WithPasswordBearer(
            os.Getenv("SALESFORCE_SDK_CLIENT_ID"),
            os.Getenv("SALESFORCE_SDK_CLIENT_SECRET"),
            os.Getenv("SALESFORCE_SDK_USERNAME"),
            os.Getenv("SALESFORCE_SDK_PASSWORD"),
            os.Getenv("SALESFORCE_SDK_SECURITY_TOKEN"),
        ),
        client.WithJWTBearer(
            os.Getenv("SALESFORCE_SDK_CLIENT_ID"),
            os.Getenv("SALESFORCE_SDK_USERNAME"),
            "../private.pem",
        ),
    ),
    client.WithLimiter(ratelimit.New(5, time.Second, 5, memory.New())),
)

The above code will attempt to login first with the password bearer flow, then the JWT bearer flow. Then it sets the client.Limiter interface to use a ratelimiting library such as github.com/beeekind/ratelimit.

We formally recommend the JWT based flow, even if many production systems default to the password bearer flow.

For a full list of available options see options.go. Also review the variable defaultOptions in client.go .


Clients are intended to fulfill the requests.Sender interface.

var result metadata.Describe 
contents, err := requests. 
    Sender(client). 
    URL("sobjects/Lead/describe").
    JSON(&result)

This provides a fluent API that can be heavily customized.

var result metadata.Describe 
contents, err := requests. 
    Sender(client). 
    URL("sobjects/Lead/describe"). 
    Header("foo", "bar"). 
    Ctx(context.WithTimeout(context.Background(), time.Minute)). 
    JSON(&result)

The client.QueryMore method is an important method for retrieving paginated records from salesforce.

var results types.QueryResponse
response, err := requests. 
    Sender(client). 
    URL("query"). 
    SQLizer(soql.Select("Id", "Name").From("Lead")). 
    Response() 

if err := requests.Unmarshal(response, &results); err != nil {
    // ...
}

Finally all methods may be used in conjunction with generated types.

type response struct {
    types.QueryResponse
    Records []*leads.Lead `json:"records"`
}

var results response
_, err := requests. 
    Sender(client). 
    URL("query"). 
    SQLizer(soql.Select("Id", "Name").From("Lead")). 
    JSON(&results) 

Documentation

Overview

Package client wraps http.Client and handles request authentication and other session state

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewHTTPClient

func NewHTTPClient(opts ...TransportOption) *http.Client

NewHTTPClient constructs a new HTTP client with the specified transport-level options.

Types

type APIVersion

type APIVersion struct {
	Label   string `json:"label"`
	URL     string `json:"url"`
	Version string `json:"version"`
}

APIVersion ...

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client ...

func Must

func Must(options ...Option) *Client

Must calls New(options...) and panics if an error occurs

func New

func New(options ...Option) (*Client, error)

New creates a new instance of client.Client . The instance may be customized by passing in client.Option types.

func (*Client) APIVersions

func (c *Client) APIVersions() (versions []*APIVersion, err error)

APIVersions returns a list of all available Salesforce versions. Generally you'll want to use the latest API version as Salesforce puts a lot of effort into backwards compatibility.

This method is called by WithLoginResponse() in order to select the latest API version by default.

func (*Client) Do

func (c *Client) Do(req *http.Request) (*http.Response, error)

Do proxies call to http.Client.Do with the following extended behavior: * Requests are only made if IsWithinAPIUsageLimit does not return an error * Any configured Limiter allows a request * Responses are parsed in order to update client.UsedAPILast24

func (*Client) IsWithinAPIUsageLimit

func (c *Client) IsWithinAPIUsageLimit() error

IsWithinAPIUsageLimit ...

func (*Client) QueryMore

func (c *Client) QueryMore(builder soql.Builder, dst interface{}, includeSoftDelete bool) (err error)

QueryMore executes a soql query on the query endpoint and returns all paginated resources. By analyzing the first and second serialized requests we can pre-compute all subsequent paginated resources and concurrently process remaining work.

This concurrent approach provides a massive performance increase when querying many records.

func (*Client) URL

func (c *Client) URL(path string) string

URL parses a url segment into a fully qualified Salesforce API request using client.instanceURL, client.apiPathPrefix, and client.apiVersion

Any fully qualified url - as indicated by the presence of the string https - is returned unmodified.

type Limiter

type Limiter interface {
	Allow(key string) (nextAllowed time.Duration, err error)
}

Limiter defines behavior for ratelimiting outgoing http requests to the Salesforce API

type LoginError

type LoginError struct {
	ErrorMessage     string `json:"error"`
	ErrorDescription string `json:"error_description"`
}

LoginError ...

func (*LoginError) Error

func (e *LoginError) Error() string

type LoginResponse

type LoginResponse struct {
	AccessToken string `json:"access_token"`
	InstanceURL string `json:"instance_url"`
	ID          string `json:"id"`
	TokenType   string `json:"token_type"`
	IssuedAt    string `json:"issued_at"`
	Signature   string `json:"signature"`
}

LoginResponse ...

type Option

type Option func(client *Client) error

Option is a functional option used to configure the client object with a clearly documented and well defaulted approach: https://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis

Options are applied after salesforce client authentication so they have full access to method calls on the client in order to dynamically retrieve configuration information from the REST API itself if desired

func WithDailyAPIMax

func WithDailyAPIMax(maxRequests24hr int64) Option

WithDailyAPIMax is the maximum number of requests allowed in a 24 hour period as seen in the company information section of your salesforce setup page. While the Salesforce client will automatically determine your daily api limit based on the "Sforce-Limit-Info" header it is useful to have a default value for calculating the apiUsageLimit threshold when the client is first initialized or if the header cannot be found.

15,000 is the default limit when you create a fresh Salesforce developer account as of 12/2020. If your limit is reached many Salesforce services will begin returning errors which could disrupt your organizations use of the Salesforce platform entirely.

Salesforce will grant additional requests in emergency situations if you contact your salesforce representative though generally by the time they respond it will be too late.

Default: 15000

func WithHTTPClient

func WithHTTPClient(httpClient *http.Client) Option

WithHTTPClient sets the client used to access the Salesforce REST API. This client should be configured similar to httppool/authhttp.go where each request includes the proper authorization headers. See WithLoginBearer for an example of how to property configure the http.Client through authhttp

func WithInstanceURL

func WithInstanceURL(instanceURL string) Option

WithInstanceURL sets the instance url representing your organizations unique hostname for accessing the salesforce REST API

a developer organization may look like https://{{ORGANIZATION_NAME}}-dev-ed.my.salesforce.com/ an enterprise organization may look like https://na150.salesforce.com/

func WithJWTBearer

func WithJWTBearer(clientID, clientUsername, privateKeyPath string) Option

WithJWTBearer ...

func WithLimiter

func WithLimiter(limiter Limiter) Option

WithLimiter ...

func WithLoginFailover

func WithLoginFailover(options ...Option) Option

WithLoginFailover ...

func WithLoginResponse

func WithLoginResponse(loginResponse *LoginResponse) Option

WithLoginResponse derives needed URL components used in all subsequent requests to Salesforce including your salesforce instanceURL, authorization bearer token, and url path prefix ("/services/data")

func WithLoginURL

func WithLoginURL(loginURL string) Option

WithLoginURL sets the login url used to authenticate salesforce.Client

Default: https://login.salesforce.com/services/oauth2/token

func WithPasswordBearer

func WithPasswordBearer(clientID, clientSecret, username, password, securityToken string) Option

WithPasswordBearer ...

func WithPathPrefix

func WithPathPrefix(urlTemplatePrefix string) Option

WithPathPrefix is the prefix used to form a a fully qualified URL for retrieving data from the Salesforce REST API. By convention this will be /services/data but in the case that future API versions choose a different format we're leaving this as a dynamically configurable option.

Note that we trim any leading or trailing "/" characters since we later join it with other url segments when preparing the full url.

Default: "services/data"

func WithUsage

func WithUsage(apiUsagePercentage float64) Option

WithUsage is the percentage of your organizations daily API requests that this library will use before returning errors. This is calculated by reading the "Sforce-Limit-Info" header returned by some types of requests. Until the header is found in a made request this limit will fall back to the WithDailyAPIMax property.

Default 0.70 representing 70%

func WithVersion

func WithVersion(apiVersion string) Option

WithVersion sets the api version for subsequent requests made to the Salesforce REST API. By default it will use the latest API version which is v50.0 as of 12/2020.

If you wish to make requests across multiple versions create multiple instances of a salesforce.Client, one for each desired version.

Salesforce keeps backwards compatibility better then many other services, though you should read the individual SLA for any service whose backwards compatibility is vital to your organization.

version is formatted as: "v50.0"

Default: v50.0

type RoundTripFunc

type RoundTripFunc func(*http.Request) (*http.Response, error)

RoundTripFunc ...

func (RoundTripFunc) RoundTrip

func (fn RoundTripFunc) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip ...

type TransportOption

type TransportOption func(http.RoundTripper) http.RoundTripper

TransportOption represents a transport-level option for an http.RoundTripper.

func TransportWithBasicAuth

func TransportWithBasicAuth(clientID, secret string) TransportOption

TransportWithBasicAuth calls http.Request.SetBasicAuth with the given values for each request

func TransportWithHeader

func TransportWithHeader(key, value string) TransportOption

TransportWithHeader appends the following key/value header to each subsequent request

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL