[WIP] minimal module awareness by joshuarubin · Pull Request #1963 · golang/dep (original) (raw)
brandur-stripe added a commit to stripe/stripe-go that referenced this pull request
Make API response accessible on returned API structs (#1054)
Make API response accessible on returned API structs
Makes an API response struct containing niceties like the raw response body, status, and request ID accessible via API resource structs returned from client functions. For example:
customer, err := customer.New(params)
fmt.Printf("request ID = %s\n", customer.LastResponse.RequestID)This is a feature that already exists in other language API libraries and which is requested occasionally here, usually for various situations involving more complex usage or desire for better observability.
-- Implementation
We introduce a few new types to make this work:
APIResponse: Represents a response from the Stripe API and includes things like request ID, status, and headers. I elected to create my own object instead of reusinghttp.Responsebecause it gives us a little more flexibility, and hides many of myriad of fields exposed by thehttpversion, which will hopefully give us a little more API stability/forward compatibility.APIResource: A struct that containsLastResponseand is meant to represent any type that can we returned from a Stripe API endpoint. A coupon is anAPIResourceand so is a list object. This struct is embedded in response structs where appropriate across the whole API surface area (e.g.Coupon,ListMeta, etc.).LastResponseGetter: A very basic interface to an object that looks like anAPIResource. This isn't strictly necessary, but gives us slightly more flexibility around the API and makes backward compatibility a little bit better for non-standard use cases (see the section on that below).
stripe.Do and other backend calls all start taking objects which are
LastResponseGetter instead of interface{}. This provides us with some
type safety around forgetting to include an embedded APIResource on
structs that should have it by making the compiler balk.
As stripe.Do finishes running a request, it generates an APIResponse
object and sets it onto the API resource type it's deserializing and
returning (e.g. a Coupon).
Errors also embed APIResource and similarly get access to the same set
of fields as response resources, although in their case some of the
fields provided in APIResponse are duplicates of what they had
already (see "Caveats" below).
-- Backwards compatibility
This is a minor breaking change in that backend implementations methods
like Do now take LastResponseGetter instead of interface{}, which
is more strict.
The good news though is that:
Very few users should be using any of these even if they're technically public. The resource-specific clients packages tend to do all the work.
Users who are broken should have a very easy time updating code. Mostly this will just involve adding
APIResourceto structs that were being passed in.
-- Naming
APIResponse: Went with this instead ofStripeResponseas we see in some other libraries because the linter will complain that it "stutters" when used outside of the package (meaning, uses the same word twice in a row), i.e.stripe.StripeResponse.APIResponsesorts nicely withAPIResourcethough, so I think it's okay.LastResponse: Copied the "last" convention from other API libraries like stripe-python.LastResponseGetter: Given an "-er" name per Go convention around small interfaces that are basically one liners -- e.g.Reader,Writer,Formatter,CloseNotifier, etc. I can see the argument that this maybe should just beAPIResourceInterface` or something like that in case we start adding new things, but I figure at that point we can either rename it, or create a parent interface that encapsulates it:type APIResourceInterface interface { LastResponseGetter }
-- Caveats
We only set the last response for top-level returned objects. For example, an
InvoiceItemis an API resource, but if it's returned under anInvoice, onlyInvoicehas a non-nilLastResponse. The same applies for all resources under list objects. I figure that doing it this way is more performant and makes a little bit more intuitive sense. Users should be able to work around it if they need to.There is some duplication between
LastResponseand some other fields that already existed onstripe.Errorbecause the latter was already exposing some of this information, e.g.RequestID. I figure this is okay: it's nice thatstripe.Erroris aLastResponseGetterfor consistency with other API resources. The duplication is a little unfortunate, but not that big of a deal.Rename
LastResponseGettertoLastResponseSetterand remove a functionUpdate stripe.go
Co-Authored-By: Olivier Bellone ob@stripe.com
- Move
APIResourceonto individual list structs instead of having it inListMeta
Co-authored-by: Brandur brandur@stripe.com Co-authored-by: Olivier Bellone ob@stripe.com
Remove all beta features from Issuing APIs
Multiple breaking API changes
PaymentIntentis now expandable onChargePercentagewas removed as a filter when listingTaxRateRemoved
RenewalIntervalonSubscriptionScheduleRemoved
CountryandRoutingNumberfromChargePaymentMethodDetailsAcssDebitStart using Go Modules
Similar to the original implementation for Go Modules in #712, here we
add a go.mod and go.sum, then proceed to use Go Modules style
import paths everywhere that include the current major revision.
Unfortunately, this may still cause trouble for Dep users who are trying to upgrade stripe-go, but the project's now had two years to help its users with basic Go Module awareness, and has chosen not to do so. It's received no commits of any kind since August 2019, and therefore would be considered unmaintained by most definitions. Elsewhere, Go Modules now seem to be the only and obvious way forward, so we're likely to see more and more users on them.
scripts/check_api_clients/main.go is also updated to be smarter about
breaking down package paths which may now include the major.
[1] golang/dep#1963
- Change v71 back to v70
Move back down to current major version so that we can test that our release script will bump it to v71 properly when the time comes.
Co-authored-by: Brandur brandur@stripe.com Co-authored-by: Olivier Bellone ob@stripe.com Co-authored-by: Remi Jannel remi@stripe.com