diff --git a/EXAMPLES.md b/EXAMPLES.md new file mode 100644 index 00000000..b0f2a1ef --- /dev/null +++ b/EXAMPLES.md @@ -0,0 +1,192 @@ +# Examples + +- [Request Options](#request-options) +- [Pagination](#pagination) + - [Page based pagination](#page-based-pagination) + - [Checkpoint pagination](#checkpoint-pagination) +- [Custom User Structs](#providing-a-custom-user-struct) + +## Request Options + +Fine-grained configuration can be provided on a per-request basis to enhance the request with specific query params, headers, or to pass it a custom context. + +> **Note** +> Not all of the API endpoints support the query parameters added by these funcs. +> Review the [API docs](https://auth0.com/docs/api/management/v2) for the full documentation of the supported parameters per endpoint. + +```go +// Example +userGrants, err := auth0API.Grant.List( + management.Context(ctx), + management.Header("MySpecialHeader","MySpecialHeaderValue"), + management.Parameter("user_id", "someUserID"), + management.Parameter("client", "someClientID"), + management.Parameter("audience", "someAPIAudience"), +) + +// Other helper funcs +management.Query() +management.ExcludeFields() +management.IncludeFields() +management.Page() +management.PerPage() +management.IncludeTotals() +management.Take() +management.From() +``` + +## Pagination + +This SDK supports both offset and checkpoint pagination. + +### Page based pagination + +When retrieving lists of resources, if no query parameters are set using the `management.PerPage` and `Management.IncludeTotals` helper funcs, then the SDK will default to sending `per_page=50` and `include_totals=true`. + +> **Note** +> The maximum value of the `per_page` query parameter is 100. + +
+ Page based pagination example + +```go +var page int +for { + clients, err := auth0API.Client.List( + management.Page(page), + management.PerPage(100), + ) + if err != nil { + return err + } + + // Accumulate here the results or check for a specific client. + + if !clients.HasNext() { + break + } + + page++ +} +``` +
+ +### Checkpoint pagination + +Checkpoint pagination can be used when you wish to retrieve more than 1000 results from certain APIs. The APIs that support checkpoint based pagination are: + +* `Log.List` (`/api/v2/logs`) +* `Organization.List` (`/api/v2/organizations`) +* `Organization.Members` (`/api/v2/organizations/{id}/members`) +* `Role.Users` (`/api/v2/roles/{id}/users`) + +
+ Checkpoint pagination example + +```go +// For the first call, only pass the `take` query parameter, the API will +// then return a `Next` value that can be used for future requests. +orgList, err := auth0API.Organization.List(management.Take(100)) +if err != nil { + log.Fatalf("err: %+v", err) +} + +if !orgList.HasNext() { + // No need to continue we can stop here. + return +} + +for { + // Pass the `next` and `take` query parameters now so + // that we can correctly paginate the organizations. + orgList, err = auth0API.Organization.List( + management.From(orgList.Next), + management.Take(100), + ) + if err != nil { + log.Fatalf("err :%+v", err) + } + + for _, org := range orgList.Organizations { + log.Printf("org %s", org.GetID()) + } + + // The `HasNext` helper func checks whether + // the API has informed us that there is + // more data to retrieve or not. + if !orgList.HasNext() { + break + } +} +``` +
+ +However, for `Log.List`, the `Next` value is not returned via the API but instead is an ID of a log entry. Determining if there are more logs to retrieved must also be done manually. + +
+ Checkpoint pagination example for Log.List + +```go +var logs []*management.Log +initialLogId := "LOGID" +for { + // Retrieve 100 logs after the specified log + logs, err = auth0API.Log.List( + management.From(logFromId), + management.Take(100), + ) + + if err != nil { + log.Fatalf("err: %+v", err) + } + + for _, logData := range logs { + log.Printf("ID %s", logData.GetID()) + log.Printf("Type %s", logData.GetType()) + + } + + // The HasNext helper cannot be used with `Log.List` so instead we check the length of the + // returned logs array. When it reaches 0 there are no more logs left to process. + if len(logs) == 0 { + break + } + + logFromId = logs[len(logs)-1].GetID() +} +``` +
+ +## Providing a custom User struct + +The `management.User` struct within the SDK only contains the properties supported by Auth0. Therefore, any extra properties added by an external identity provider will not be included within the struct returned from the SDK APIs. To expose these custom properties, we recommend creating a custom struct and then manually calling the API via the lower level request functionality exposed by the SDK, as shown below. + +First, define a custom struct that embeds the `management.User` struct exposed by the SDK, and add any helper funcs required to safely access your custom values. + +```go +// Define a custom struct that embeds the `management.User` struct exposed by the SDK. +type CustomUser struct { + management.User + OurCustomID *string `json:"custom_id,omitempty"` +} + +// Create a helper func that will safely retrieve the `OurCustomId` value from CustomUser in the +// cases where it may be nil. +func (u *CustomUser) GetOurCustomID() string { + if u == nil || u.OurCustomID == nil { + return "" + } + return *u.OurCustomID +} +``` + +Then, create a request using the lower level request functionality exposed by the SDK. + +```go +var user CustomUser +err := auth0API.Request(http.MethodGet, auth0API.URI("users", "auth0|63cfb8ca89c31c3f33f1dffd"), &user) +if err != nil { + log.Fatalf("error was %+v", err) +} +log.Printf("User %s", user.GetOurCustomID()) +``` \ No newline at end of file diff --git a/README.md b/README.md index e0960680..2e303fb4 100644 --- a/README.md +++ b/README.md @@ -24,14 +24,15 @@ Go SDK for the [Auth0](https://auth0.com/) Management API. - [Godoc](https://pkg.go.dev/github.com/auth0/go-auth0) - explore the Go SDK documentation. - [Management API docs](https://auth0.com/docs/api/management/v2) - explore the Auth0 Management API that this SDK interacts with. - [Docs site](https://www.auth0.com/docs) — explore our docs site and learn more about Auth0. +- [Examples](./EXAMPLES.md) - Further examples around usage of the SDK. ## Getting started ### Requirements -- Go 1.17+ +This library follows the [same support policy as Go](https://go.dev/doc/devel/release#policy). The last two major Go releases are actively supported and compatibility issues will be fixed. While you may find that older versions of Go may work, we will not actively test and fix compatibility issues with these versions. -**go-auth0** tracks [Go's version support policy](https://go.dev/doc/devel/release#policy). +- Go 1.19+ ### Installation @@ -104,59 +105,6 @@ the background by retrying the API request when the limit is lifted. > The SDK does not prevent `http.StatusTooManyRequests` errors, instead it waits for the rate limit to be reset based on > the value of the `X-Rate-Limit-Reset` header as the amount of seconds to wait. -### Request Options - -Fine-grained configuration can be provided on a per-request basis to enhance the request with specific query params, headers -or to pass it a custom context. - -```go -// Example -userGrants, err := auth0API.Grant.List( - management.Context(ctx) - management.Header("MySpecialHeader","MySpecialHeaderValue") - management.Parameter("user_id", "someUserID"), - management.Parameter("client", "someClientID"), - management.Parameter("audience", "someAPIAudience"), -) - -// Other helper funcs. -management.Query() -management.ExcludeFields() -management.IncludeFields() -management.Page() -management.PerPage() -management.Take() -``` - -### Pagination - -When retrieving lists of resources, if no query parameters are passed, -the following query parameters will get added by default: `?per_page=50,include_totals=true`. - -> **Note** -> The maximum value of the per_page query param is 100. - -To get more than 50 results (the default), iterate through the returned pages. - -```go -// Example -var page int -for { - clients, err := auth0API.Client.List(management.Page(page)) - if err != nil { - return err - } - - // Accumulate here the results or check for a specific client. - - if !clients.HasNext() { - break - } - - page++ -} -``` - ## Feedback ### Contributing @@ -188,7 +136,3 @@ Please do not report security vulnerabilities on the public Github issue tracker

Auth0 is an easy to implement, adaptable authentication and authorization platform.
To learn more checkout Why Auth0?

This project is licensed under the MIT license. See the LICENSE file for more info.

- - -## License -[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fauth0%2Fgo-auth0.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fauth0%2Fgo-auth0?ref=badge_large) \ No newline at end of file