Documentation ¶
Overview ¶
Package gomo provides an API client for Moltin's headless ecommerce API.
Sign up for an account at https://moltin.com.
By Andrew Waters and the team at Moltin. Contributions are most welcome.
Getting Started ¶
Create a client object, and authenticate:
client := gomo.NewClient() err := client.Authenticate()
By default the environment variables MOLTIN_CLIENT_ID and MOLTIN_CLIENT_SECRET will be used for authentication.
Requests are made to the API via the Get(), Post(), Put() and Delete() functions, each of which accepts a path and a number of resources. These resources can set the target for the returned data or the body of the request, as will as configuring various other request options.
Requests and their responses are usually marshalled into core types representing the various objects in the Moltin API.
So to read category ID c82d2f00-bc66-4c7d-984a-8765222abb98, along with its associated products one might use:
id := "c82d2f00-bc66-4c7d-984a-8765222abb98" var category core.Category var included struct { Products []core.Product `json:"products"` } err := client.Get( "categories/"+id, gomo.Include("products"), gomo.Included(&included), gomo.Data(&category) ) if err != nil { log.Fatal(err) } fmt.Printf("Category %s has products:\n", category.Name) for _, product := range included.Products { fmt.Println(product.ID) }
Flows ¶
Flows allow arbitrary data to be associated with objects. To cope with them in Go, create a struct for the flow fields and embed the core object to access the core fields, eg:
type MyProduct struct { core.Product Stars int `json:"stars"` } var product MyProduct err = client.Get( "/products/8610c22b-f3a5-48a6-a680-8e8902a74aac", gomo.Data(&product), ) if err != nil { log.Fatal(err) } fmt.Printf( "Product %s has %d stars\n", product.Product.Name, product.Stars, )
Example ¶
package main import ( "fmt" "log" "github.com/moltin/gomo" "github.com/moltin/gomo/core" ) func main() { // create a new client with client credentials client := gomo.NewClient( gomo.ClientCredentials( "client_id", "client_secret", ), ) // handle an authentication error if err := client.Authenticate(); err != nil { log.Fatal(err) } // create a product product := core.Product{ Name: "My new product", } var executionTime *gomo.APIExecution // send the create request err := client.Post( "products", gomo.Body(product), gomo.Data(&product), gomo.ExecutionTime(&executionTime), ) if err != nil { log.Fatal(err) } // print the execution time metric log.Println("Execution time:", executionTime.Elapsed()) // update a product field product.Name = "Updated Product" // send the update request err = client.Put( fmt.Sprintf("products/%s", product.ID), gomo.Body(product), ) if err != nil { log.Fatal(err) } // delete the product err = client.Delete(fmt.Sprintf("products/%s", product.ID)) if err != nil { log.Fatal(err) } }
Output:
Index ¶
- func Iterate(limit int, f func(RequestResource) error) error
- func MorePages(meta core.Meta) bool
- func NextPage(meta core.Meta) (int, int)
- type APIError
- type APIExecution
- type Client
- func (c *Client) Authenticate() error
- func (c *Client) Delete(endpoint string, resource ...RequestResource) error
- func (c *Client) DisableDebug()
- func (c *Client) EnableDebug()
- func (c *Client) Get(endpoint string, resource ...RequestResource) error
- func (c *Client) GrantType() string
- func (c *Client) Log(msgs ...interface{})
- func (c *Client) Post(endpoint string, resource ...RequestResource) error
- func (c *Client) Put(endpoint string, resource ...RequestResource) error
- type ClientOption
- func APIVersion(apiVersion string) ClientOption
- func ClientCredentials(clientID string, clientSecret string) ClientOption
- func Debug() ClientOption
- func Endpoint(endpoint string) ClientOption
- func HTTPClient(client *http.Client) ClientOption
- func ImplicitCredentials(clientID string) ClientOption
- func Logger(logger func(*Client, interface{})) ClientOption
- type RequestResource
- func Body(target interface{}) RequestResource
- func Data(target interface{}) RequestResource
- func Errors(target *[]APIError) RequestResource
- func ExecutionTime(e **APIExecution) RequestResource
- func Filter(filter string) RequestResource
- func Form(target interface{}) RequestResource
- func Include(include string) RequestResource
- func Included(target interface{}) RequestResource
- func Links(target interface{}) RequestResource
- func Meta(target interface{}) RequestResource
- func Paginate(offset, limit int) RequestResource
- func Sort(by string) RequestResource
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Iterate ¶
func Iterate(limit int, f func(RequestResource) error) error
Iterate calls the function with a RequestResource that should be passed to a Get() request. The function is called for each page of size limit. If the function returns an error at any point the iteration stops and the error is returned.
Example ¶
package main import ( "log" "github.com/moltin/gomo" "github.com/moltin/gomo/core" ) func main() { client := gomo.NewClient() _ = client.Authenticate() gomo.Iterate( 100, func(paginate gomo.RequestResource) error { page := []core.Product{} err := client.Get("product", gomo.Data(&page)) if err != nil { log.Fatal(err) } log.Printf("%d products in page\n", len(page)) return nil }, ) }
Output:
func MorePages ¶
MorePages returns true is the meta suggests there are more results available
Example ¶
package main import ( "fmt" "log" "github.com/moltin/gomo" "github.com/moltin/gomo/core" ) func main() { client := gomo.NewClient() _ = client.Authenticate() var orders []core.Order var meta core.Meta err := client.Get("orders", gomo.Data(&orders), gomo.Meta(&meta)) if err != nil { log.Fatal(err) } fmt.Printf("Got %d orders.\n", len(orders)) if gomo.MorePages(meta) { fmt.Println("There are more orders to fetch!") } }
Output:
func NextPage ¶
NextPage advances the supplied Meta to the next page by returning a new offset and limit
Example ¶
package main import ( "fmt" "log" "github.com/moltin/gomo" "github.com/moltin/gomo/core" ) func main() { client := gomo.NewClient() _ = client.Authenticate() // Note that Iterate() is a neater way of doing this. var allOrders []core.Order offset := 0 limit := 100 for { var page []core.Order var meta core.Meta err := client.Get( "orders", gomo.Data(&page), gomo.Meta(&meta), gomo.Paginate(offset, limit), ) if err != nil { log.Fatal(err) } allOrders = append(allOrders, page...) if !gomo.MorePages(meta) { break } offset, limit = gomo.NextPage(meta) } fmt.Printf("Got all the orders, a total of %d\n", len(allOrders)) }
Output:
Types ¶
type APIError ¶
type APIError struct { Status int `json:"status"` Detail string `json:"detail"` Title string `json:"title"` }
APIError is an error returned by the API so that you can include error speciifc logic in your own implementation
if error.Status == 404 { // create something }
type APIExecution ¶
type APIExecution struct { StartTime time.Time EndTime time.Time // contains filtered or unexported fields }
APIExecution records the execution time of the call
func (APIExecution) Elapsed ¶
func (e APIExecution) Elapsed() time.Duration
Elapsed returns the duration of the timer
type Client ¶
type Client struct { APIVersion string Endpoint string AccessToken string Debug bool Logs []interface{} Logger func(*Client, interface{}) // contains filtered or unexported fields }
Client is the main client struct
func NewClient ¶
func NewClient(options ...ClientOption) Client
NewClient creates a new client for you to make requests with. It is configured by passing in list of option functions.
Example ¶
package main import ( "log" "github.com/moltin/gomo" ) func main() { client := gomo.NewClient( gomo.ClientCredentials( "client_id", "client_secret", ), gomo.Endpoint("http://test.example.com/"), gomo.Debug(), ) log.Println(client.APIVersion) }
Output:
func (*Client) Authenticate ¶
Authenticate makes a call to get the access token for the client's credentials
func (*Client) Delete ¶
func (c *Client) Delete(endpoint string, resource ...RequestResource) error
Delete makes a DELETE request to the API
func (*Client) DisableDebug ¶
func (c *Client) DisableDebug()
DisableDebug stops logs form API calls
func (*Client) EnableDebug ¶
func (c *Client) EnableDebug()
EnableDebug logs debugging info from the API calls
func (*Client) Get ¶
func (c *Client) Get(endpoint string, resource ...RequestResource) error
Get makes a GET request to the API
Example ¶
package main import ( "fmt" "log" "github.com/moltin/gomo" "github.com/moltin/gomo/core" ) func main() { client := gomo.NewClient() _ = client.Authenticate() id := "96a52ef6-62c0-47ad-809d-6390d7727d49" type MyProduct struct { core.Product FlowField string `json:"flow_field"` } var product MyProduct err := client.Get( fmt.Sprintf("products/%s", id), gomo.Data(&product), ) if err != nil { log.Fatal(err) } fmt.Printf( "Product %s has flow field %s\n", product.Product.ID, product.FlowField, ) }
Output:
func (*Client) Post ¶
func (c *Client) Post(endpoint string, resource ...RequestResource) error
Post makes a POST request to the API
Example ¶
package main import ( "fmt" "log" "github.com/moltin/gomo" "github.com/moltin/gomo/core" ) func main() { client := gomo.NewClient() _ = client.Authenticate() type MyProduct struct { core.Product FlowField string `json:"flow_field"` } product := MyProduct{ Product: core.Product{ Name: "foo", }, FlowField: "foo custom", } err := client.Post( "products", gomo.Body(product), gomo.Data(&product), ) if err != nil { log.Fatal(err) } fmt.Printf("Created product %s\n", product.Product.ID) }
Output:
type ClientOption ¶
type ClientOption func(*Client)
ClientOption are functions that configure a Client
func APIVersion ¶
func APIVersion(apiVersion string) ClientOption
APIVersion configures the API version for the client
func ClientCredentials ¶
func ClientCredentials(clientID string, clientSecret string) ClientOption
ClientCredentials configures a client with client credentials
Example ¶
package main import ( "github.com/moltin/gomo" ) func main() { creds := gomo.ClientCredentials( "client_id", "client_secret", ) gomo.NewClient(creds) }
Output:
func Endpoint ¶
func Endpoint(endpoint string) ClientOption
Endpoint configures the API endpoint for the client
func HTTPClient ¶
func HTTPClient(client *http.Client) ClientOption
HTTPClient configures a client to use an http.Client
func ImplicitCredentials ¶
func ImplicitCredentials(clientID string) ClientOption
ImplicitCredentials configures a client with implicit credentials
Example ¶
package main import ( "github.com/moltin/gomo" ) func main() { creds := gomo.ImplicitCredentials( "client_id", ) gomo.NewClient(creds) }
Output:
func Logger ¶
func Logger(logger func(*Client, interface{})) ClientOption
Logger configures a client to use a logger
type RequestResource ¶
type RequestResource func(*wrapper)
RequestResource are functions that provide a request with the resources it requires. This includes Body() which is the body of the request, Data() which sets the target struct for the returned data, etc
func Body ¶
func Body(target interface{}) RequestResource
Body sets the body for a Post() or Put() request
func Data ¶
func Data(target interface{}) RequestResource
Data sets a target for a responses data resource
func Errors ¶
func Errors(target *[]APIError) RequestResource
Errors sets a target for the responses errors
func ExecutionTime ¶
func ExecutionTime(e **APIExecution) RequestResource
ExecutionTime returns a pointer to the ExecutionTime for the request
func Filter ¶
func Filter(filter string) RequestResource
Filter adds a filter to a query, prepending to any existing filters. See https://docs.moltin.com/api/basics/filtering
Example ¶
package main import ( "fmt" "log" "github.com/moltin/gomo" "github.com/moltin/gomo/core" ) func main() { client := gomo.NewClient() _ = client.Authenticate() var draftProducts []core.Product err := client.Get( "products", gomo.Filter("eq(status,draft)"), gomo.Data(&draftProducts), ) if err != nil { log.Fatal(err) } fmt.Println("Draft products:") for _, product := range draftProducts { fmt.Println(product.ID) } }
Output:
func Form ¶
func Form(target interface{}) RequestResource
Form sets multipart/form data for a Post() or Put() request
Example ¶
package main import ( "fmt" "log" "os" "github.com/moltin/gomo" "github.com/moltin/gomo/core" "github.com/moltin/gomo/form" ) func main() { client := gomo.NewClient() _ = client.Authenticate() img, err := os.Open("/tmp/product.jpg") if err != nil { log.Fatal(err) } file := core.File{ FileName: "product.jpg", Public: true, MimeType: "image/jpeg", File: &form.File{ Name: "product.jpg", Content: img, }, } err = client.Post( "files", gomo.Form(file), gomo.Data(&file), ) if err != nil { log.Fatal(err) } fmt.Printf("File ID: %s\n", file.ID) }
Output:
func Include ¶
func Include(include string) RequestResource
Include adds a resource to be included in the request. See https://docs.moltin.com/api/basics/includes
Example ¶
package main import ( "fmt" "log" "github.com/moltin/gomo" "github.com/moltin/gomo/core" ) func main() { client := gomo.NewClient() _ = client.Authenticate() id := "c82d2f00-bc66-4c7d-984a-8765222abb98" var included struct { Products []core.Product `json:"products"` } err := client.Get( "categories/"+id, gomo.Include("products"), gomo.Included(&included), ) if err != nil { log.Fatal(err) } fmt.Printf("Category %s has products:\n", id) for _, product := range included.Products { fmt.Println(product.ID) } }
Output:
func Included ¶
func Included(target interface{}) RequestResource
Included sets a target for a responses included resource
func Links ¶
func Links(target interface{}) RequestResource
Links sets a target for a responses links resource
func Meta ¶
func Meta(target interface{}) RequestResource
Meta sets the a for a responses meta resource
func Paginate ¶
func Paginate(offset, limit int) RequestResource
Paginate sets the page to select bases on the offset and limit. See https://docs.moltin.com/api/basics/pagination
func Sort ¶
func Sort(by string) RequestResource
Sort sorts the results. See https://docs.moltin.com/api/basics/sorting
Example ¶
package main import ( "fmt" "log" "github.com/moltin/gomo" "github.com/moltin/gomo/core" ) func main() { client := gomo.NewClient() _ = client.Authenticate() var productsByName []core.Product err := client.Get( "products", gomo.Sort("name"), gomo.Data(&productsByName), ) if err != nil { log.Fatal(err) } fmt.Println("Product names:") for _, product := range productsByName { fmt.Println(product.Name) } }
Output: