client

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Nov 9, 2025 License: MIT Imports: 18 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ScopeBusinessAPI = "business.api"
	ScopeSchoolAPI   = "school.api"
)

OAuth scope constants

View Source
const (
	DefaultBaseURL = "https://api-business.apple.com/v1"
)

API Base URL

View Source
const (
	DefaultJWTAudience = "appstoreconnect-v1"
)

Default OAuth audience

View Source
const (
	DefaultOAuthTokenEndpoint = "https://account.apple.com/auth/oauth2/v2/token"
)

Default OAuth endpoints

Variables

View Source
var (
	ErrNoNextPage      = fmt.Errorf("no next page available")
	ErrInvalidCursor   = fmt.Errorf("invalid pagination cursor")
	ErrAuthFailed      = fmt.Errorf("authentication failed")
	ErrRateLimited     = fmt.Errorf("rate limit exceeded")
	ErrInvalidResponse = fmt.Errorf("invalid response format")
)

Common error types

Functions

func HasNextPage

func HasNextPage(links *Links) bool

HasNextPage checks if there is a next page available

func HasPrevPage

func HasPrevPage(links *Links) bool

HasPrevPage checks if there is a previous page available

func LoadPrivateKeyFromEnv

func LoadPrivateKeyFromEnv() (any, error)

LoadPrivateKeyFromEnv loads a private key from the environment variable APPLE_PRIVATE_KEY_PATH

func LoadPrivateKeyFromFile

func LoadPrivateKeyFromFile(filePath string) (any, error)

LoadPrivateKeyFromFile loads a private key (RSA or ECDSA) from a PEM file

func ParsePrivateKey

func ParsePrivateKey(keyData []byte) (any, error)

ParsePrivateKey parses a private key (RSA or ECDSA) from PEM-encoded data

func ValidatePrivateKey

func ValidatePrivateKey(privateKey any) error

ValidatePrivateKey validates that the private key is suitable for JWT signing

Types

type APIError

type APIError struct {
	ID     string          `json:"id,omitempty"`
	Status string          `json:"status"`
	Code   string          `json:"code"`
	Title  string          `json:"title"`
	Detail string          `json:"detail"`
	Source *APIErrorSource `json:"source,omitempty"`
	Links  *ErrorLinks     `json:"links,omitempty"`
	Meta   *APIErrorMeta   `json:"meta,omitempty"`
}

APIError represents a single error from the Apple Business Manager API

func (*APIError) Error

func (e *APIError) Error() string

type APIErrorMeta

type APIErrorMeta struct {
	// Can contain any key-value pairs as specified in the API documentation
	AdditionalProperties map[string]any `json:"-"`
}

APIErrorMeta contains additional error metadata

func (*APIErrorMeta) MarshalJSON

func (m *APIErrorMeta) MarshalJSON() ([]byte, error)

MarshalJSON implements custom marshaling for APIErrorMeta

func (*APIErrorMeta) UnmarshalJSON

func (m *APIErrorMeta) UnmarshalJSON(data []byte) error

UnmarshalJSON implements custom unmarshaling for APIErrorMeta

type APIErrorResponse

type APIErrorResponse struct {
	ErrorCode string         `json:"error_code"`
	Message   string         `json:"message"`
	Details   map[string]any `json:"details,omitempty"`
}

APIErrorResponse represents the legacy error structure (keeping for backward compatibility)

type APIErrorSource

type APIErrorSource struct {
	JsonPointer *JsonPointer `json:"jsonPointer,omitempty"`
	Parameter   *Parameter   `json:"parameter,omitempty"`
}

APIErrorSource represents the source of an error (JsonPointer or Parameter)

type APIKeyAuth

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

APIKeyAuth implements simple API key authentication

func NewAPIKeyAuth

func NewAPIKeyAuth(apiKey, header string) *APIKeyAuth

NewAPIKeyAuth creates a new API key authentication provider

func (*APIKeyAuth) ApplyAuth

func (a *APIKeyAuth) ApplyAuth(req *resty.Request) error

ApplyAuth applies API key authentication to the request

type APIResponse

type APIResponse[T any] struct {
	Data  []T   `json:"data"`
	Meta  Meta  `json:"meta"`
	Links Links `json:"links"`
}

APIResponse represents the standard API response structure

type AuthProvider

type AuthProvider interface {
	ApplyAuth(req *resty.Request) error
}

AuthProvider interface for different authentication methods

type Client

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

Client represents the main Apple Business Manager API client

func NewTransport

func NewTransport(config Config) (*Client, error)

NewTransport creates a new HTTP transport for Apple Business Manager API

func NewTransportFromEnv

func NewTransportFromEnv() (*Client, error)

NewTransportFromEnv creates a transport using environment variables Expects: APPLE_KEY_ID, APPLE_ISSUER_ID, APPLE_PRIVATE_KEY_PATH

func NewTransportFromFile

func NewTransportFromFile(keyID, issuerID, privateKeyPath string) (*Client, error)

NewTransportFromFile creates a transport using credentials from files

func (*Client) ApplyOptions

func (c *Client) ApplyOptions(opts ...ClientOptionFunc) error

ApplyOptions applies the given options to the client.

func (*Client) Close

func (c *Client) Close() error

Close closes the HTTP client and cleans up resources

func (*Client) Delete

func (c *Client) Delete(ctx context.Context, path string, queryParams map[string]string, headers map[string]string, result any) error

Delete executes a DELETE request following Resty v3 best practices. Supports query parameters for filtering or specifying deletion criteria.

This method uses Resty's SetQueryParam for URL parameters and follows RESTful conventions for resource deletion operations.

Reference: https://resty.dev/docs/request-query-params/ Reference: https://resty.dev/docs/response-auto-parse/

func (*Client) DeleteWithBody

func (c *Client) DeleteWithBody(ctx context.Context, path string, body any, headers map[string]string, result any) error

DeleteWithBody executes a DELETE request with body (for bulk operations). Useful for bulk deletion operations where multiple resources are specified in the request body.

While not always RESTful, some APIs require request bodies for DELETE operations to specify multiple resources or complex deletion criteria.

Reference: https://resty.dev/docs/request-body-types/

func (*Client) Get

func (c *Client) Get(ctx context.Context, path string, queryParams map[string]string, headers map[string]string, result any) error

Get executes a GET request following Resty v3 best practices. Supports query parameters, custom headers, and automatic response parsing.

This method uses Resty's SetQueryParam for URL parameters and SetHeader for custom headers. The response is automatically unmarshaled into the provided result any.

Reference: https://resty.dev/docs/request-query-params/ Reference: https://resty.dev/docs/response-auto-parse/

func (*Client) GetAllPages

func (c *Client) GetAllPages(ctx context.Context, path string, queryParams map[string]string, headers map[string]string, processPage func([]byte) error) error

GetAllPages retrieves all pages of results by following pagination links

func (*Client) GetHTTPClient

func (c *Client) GetHTTPClient() *resty.Client

GetHTTPClient returns the underlying HTTP client for testing purposes

func (*Client) GetNextPage

func (c *Client) GetNextPage(ctx context.Context, nextURL string, headers map[string]string, result any) error

GetNextPage extracts the next page URL from links and makes a request

func (*Client) GetPaginated

func (c *Client) GetPaginated(ctx context.Context, path string, queryParams map[string]string, headers map[string]string, result any) error

GetPaginated executes a paginated GET request

func (*Client) Patch

func (c *Client) Patch(ctx context.Context, path string, body any, headers map[string]string, result any) error

Patch executes a PATCH request following Resty v3 best practices. Typically used for partial updates of existing resources.

The body parameter is automatically marshaled to JSON using Resty's SetBody method. Follows RESTful conventions for partial resource modifications.

Reference: https://resty.dev/docs/request-body-types/ Reference: https://resty.dev/docs/response-auto-parse/

func (*Client) Post

func (c *Client) Post(ctx context.Context, path string, body any, headers map[string]string, result any) error

Post executes a POST request with JSON body following Resty v3 best practices. Automatically sets Content-Type to application/json and handles request body serialization.

The body parameter is automatically marshaled to JSON using Resty's SetBody method. Custom headers can be provided to override defaults or add additional headers.

Reference: https://resty.dev/docs/request-body-types/ Reference: https://resty.dev/docs/response-auto-parse/

func (*Client) PostMultipart

func (c *Client) PostMultipart(ctx context.Context, path string, files map[string]string, fields map[string]string, result any) error

PostMultipart executes a POST request with multipart form data following Resty v3 best practices. Supports file uploads and form fields in a single multipart/form-data request.

This method uses Resty's SetFile for file uploads and SetFormData for form fields. Automatically sets the appropriate Content-Type header for multipart requests.

Files map: fieldName -> filePath Fields map: fieldName -> fieldValue

Reference: https://resty.dev/docs/multipart/ Reference: https://resty.dev/docs/form-data/

func (*Client) PostWithQuery

func (c *Client) PostWithQuery(ctx context.Context, path string, queryParams map[string]string, body any, headers map[string]string, result any) error

PostWithQuery executes a POST request with both body and query parameters. Combines the functionality of POST requests with URL query parameter support.

This method is useful for APIs that require both request body data and URL parameters. The body is JSON-serialized while query parameters are added to the URL.

Reference: https://resty.dev/docs/request-query-params/ Reference: https://resty.dev/docs/request-body-types/

func (*Client) Put

func (c *Client) Put(ctx context.Context, path string, body any, headers map[string]string, result any) error

Put executes a PUT request following Resty v3 best practices. Typically used for updating existing resources with complete replacement.

The body parameter is automatically marshaled to JSON using Resty's SetBody method. Follows RESTful conventions for resource updates and modifications.

Reference: https://resty.dev/docs/request-body-types/ Reference: https://resty.dev/docs/response-auto-parse/

func (*Client) QueryBuilder

func (c *Client) QueryBuilder() interfaces.ServiceQueryBuilder

QueryBuilder returns a new query builder instance

type ClientOptionFunc

type ClientOptionFunc func(*Client) error

ClientOptionFunc can be used to customize a new Apple Business Manager API client.

func WithAuth

func WithAuth(auth AuthProvider) ClientOptionFunc

WithAuth sets the authentication provider for the client.

func WithBaseURL

func WithBaseURL(urlStr string) ClientOptionFunc

WithBaseURL sets the base URL for API requests to a custom endpoint.

func WithDebug

func WithDebug(debug bool) ClientOptionFunc

WithDebug enables debug mode for the HTTP client.

func WithErrorHandler

func WithErrorHandler(handler *ErrorHandler) ClientOptionFunc

WithErrorHandler sets a custom error handler.

func WithLogger

func WithLogger(logger *zap.Logger) ClientOptionFunc

WithLogger can be used to configure a custom logger.

func WithProxy

func WithProxy(proxyURL string) ClientOptionFunc

WithProxy sets a proxy for the HTTP client.

func WithRetryCount

func WithRetryCount(retryCount int) ClientOptionFunc

WithRetryCount sets the maximum number of retries for failed requests.

func WithRetryMaxWaitTime

func WithRetryMaxWaitTime(maxWait time.Duration) ClientOptionFunc

WithRetryMaxWaitTime sets the maximum wait time between retries.

func WithRetryWaitTime

func WithRetryWaitTime(retryWait time.Duration) ClientOptionFunc

WithRetryWaitTime sets the wait time between retries.

func WithTimeout

func WithTimeout(timeout time.Duration) ClientOptionFunc

WithTimeout sets the timeout for all HTTP requests.

func WithUserAgent

func WithUserAgent(userAgent string) ClientOptionFunc

WithUserAgent sets a custom user agent string for all requests.

type Config

type Config struct {
	BaseURL    string
	Auth       AuthProvider
	Logger     *zap.Logger
	Timeout    time.Duration
	RetryCount int
	RetryWait  time.Duration
	UserAgent  string
	Debug      bool
}

Config holds configuration for the client

type ErrorHandler

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

ErrorHandler centralizes error handling for all API requests

func NewErrorHandler

func NewErrorHandler(logger *zap.Logger) *ErrorHandler

NewErrorHandler creates a new error handler

func (*ErrorHandler) HandleError

func (eh *ErrorHandler) HandleError(resp *resty.Response, errorResp *ErrorResponse) error

HandleError processes API error responses and returns structured errors

type ErrorLinks struct {
	About      string                `json:"about,omitempty"`
	Associated *ErrorLinksAssociated `json:"associated,omitempty"`
}

ErrorLinks contains error-related links

type ErrorLinksAssociated

type ErrorLinksAssociated struct {
	Href string                    `json:"href"`
	Meta *ErrorLinksAssociatedMeta `json:"meta,omitempty"`
}

ErrorLinksAssociated represents associated error links

type ErrorLinksAssociatedMeta

type ErrorLinksAssociatedMeta struct {
	// Can contain any key-value pairs as specified in the API
	AdditionalProperties map[string]any `json:"-"`
}

ErrorLinksAssociatedMeta contains metadata for associated error links

func (*ErrorLinksAssociatedMeta) MarshalJSON

func (m *ErrorLinksAssociatedMeta) MarshalJSON() ([]byte, error)

MarshalJSON implements custom marshaling for ErrorLinksAssociatedMeta

func (*ErrorLinksAssociatedMeta) UnmarshalJSON

func (m *ErrorLinksAssociatedMeta) UnmarshalJSON(data []byte) error

UnmarshalJSON implements custom unmarshaling for ErrorLinksAssociatedMeta

type ErrorResponse

type ErrorResponse struct {
	Errors []APIError `json:"errors"`
}

ErrorResponse represents the complete error response structure returned by the API

type JWTAuth

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

JWTAuth implements OAuth 2.0 JWT-based authentication for Apple Business Manager API

func NewJWTAuth

func NewJWTAuth(config JWTAuthConfig) *JWTAuth

NewJWTAuth creates a new OAuth 2.0 JWT authentication provider

func (*JWTAuth) ApplyAuth

func (j *JWTAuth) ApplyAuth(req *resty.Request) error

ApplyAuth applies OAuth 2.0 authentication to the request

func (*JWTAuth) ForceRefresh

func (j *JWTAuth) ForceRefresh()

ForceRefresh forces a token refresh on the next request

type JWTAuthConfig

type JWTAuthConfig struct {
	KeyID      string
	IssuerID   string
	PrivateKey any    // Can be *rsa.PrivateKey or *ecdsa.PrivateKey
	Audience   string // Usually "appstoreconnect-v1"
	Scope      string // "business.api" or "school.api"
}

JWTAuthConfig holds configuration for JWT authentication

type JsonPointer

type JsonPointer struct {
	Pointer string `json:"pointer"`
}

JsonPointer represents a JSON pointer source

type Links struct {
	Self  string `json:"self,omitempty"`
	First string `json:"first,omitempty"`
	Next  string `json:"next,omitempty"`
	Prev  string `json:"prev,omitempty"`
	Last  string `json:"last,omitempty"`
}

Links contains pagination navigation links matching Apple's API format

type Meta

type Meta struct {
	Paging *Paging `json:"paging,omitempty"`
}

Meta contains pagination metadata matching Apple's API format

type PaginationOptions

type PaginationOptions struct {
	Limit  int    `json:"limit,omitempty"`
	Cursor string `json:"cursor,omitempty"`
}

PaginationOptions represents common pagination parameters for Apple's API

func (*PaginationOptions) AddToQueryBuilder

AddToQueryBuilder adds pagination options to a query builder

type Paging

type Paging struct {
	Total      int    `json:"total,omitempty"`
	Limit      int    `json:"limit,omitempty"`
	NextCursor string `json:"nextCursor,omitempty"`
}

Paging contains pagination information matching Apple's API format

type Parameter

type Parameter struct {
	Parameter string `json:"parameter"`
}

Parameter represents a query parameter source

type QueryBuilder

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

QueryBuilder provides a fluent interface for building query parameters

func NewQueryBuilder

func NewQueryBuilder() *QueryBuilder

NewQueryBuilder creates a new query builder

func (*QueryBuilder) AddBool

func (qb *QueryBuilder) AddBool(key string, value bool) interfaces.QueryBuilder

AddBool adds a boolean parameter

func (*QueryBuilder) AddCustom

func (qb *QueryBuilder) AddCustom(key, value string) interfaces.QueryBuilder

AddCustom adds a custom parameter with any value

func (*QueryBuilder) AddIfNotEmpty

func (qb *QueryBuilder) AddIfNotEmpty(key, value string) interfaces.QueryBuilder

AddIfNotEmpty adds a parameter only if the value is not empty

func (*QueryBuilder) AddIfTrue

func (qb *QueryBuilder) AddIfTrue(condition bool, key, value string) interfaces.QueryBuilder

AddIfTrue adds a parameter only if the condition is true

func (*QueryBuilder) AddInt

func (qb *QueryBuilder) AddInt(key string, value int) interfaces.QueryBuilder

AddInt adds an integer parameter if the value is greater than 0

func (*QueryBuilder) AddInt64

func (qb *QueryBuilder) AddInt64(key string, value int64) interfaces.QueryBuilder

AddInt64 adds an int64 parameter if the value is greater than 0

func (*QueryBuilder) AddIntSlice

func (qb *QueryBuilder) AddIntSlice(key string, values []int) interfaces.QueryBuilder

AddIntSlice adds an integer slice parameter as comma-separated values

func (*QueryBuilder) AddString

func (qb *QueryBuilder) AddString(key, value string) interfaces.QueryBuilder

AddString adds a string parameter if the value is not empty

func (*QueryBuilder) AddStringSlice

func (qb *QueryBuilder) AddStringSlice(key string, values []string) interfaces.QueryBuilder

AddStringSlice adds a string slice parameter as comma-separated values

func (*QueryBuilder) AddTime

func (qb *QueryBuilder) AddTime(key string, value time.Time) interfaces.QueryBuilder

AddTime adds a time parameter in RFC3339 format if the time is not zero

func (*QueryBuilder) Build

func (qb *QueryBuilder) Build() map[string]string

Build returns the final map of query parameters

func (*QueryBuilder) BuildString

func (qb *QueryBuilder) BuildString() string

BuildString returns the query parameters as a URL-encoded string

func (*QueryBuilder) Clear

func (qb *QueryBuilder) Clear() interfaces.QueryBuilder

Clear removes all parameters

func (*QueryBuilder) Count

func (qb *QueryBuilder) Count() int

Count returns the number of parameters

func (*QueryBuilder) Get

func (qb *QueryBuilder) Get(key string) string

Get retrieves a parameter value

func (*QueryBuilder) Has

func (qb *QueryBuilder) Has(key string) bool

Has checks if a parameter exists

func (*QueryBuilder) IsEmpty

func (qb *QueryBuilder) IsEmpty() bool

IsEmpty returns true if no parameters are set

func (*QueryBuilder) Merge

func (qb *QueryBuilder) Merge(other map[string]string) interfaces.QueryBuilder

Merge merges parameters from another query builder or map

func (*QueryBuilder) Remove

func (qb *QueryBuilder) Remove(key string) interfaces.QueryBuilder

Remove removes a parameter

type TokenResponse

type TokenResponse struct {
	AccessToken string `json:"access_token"`
	TokenType   string `json:"token_type"`
	ExpiresIn   int    `json:"expires_in"`
	Scope       string `json:"scope"`
}

TokenResponse represents the OAuth 2.0 token response from Apple

Jump to

Keyboard shortcuts

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