Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compile-time safety for api call parameters and types #211

Closed
ghost opened this issue Aug 26, 2015 · 23 comments
Closed

compile-time safety for api call parameters and types #211

ghost opened this issue Aug 26, 2015 · 23 comments
Labels

Comments

@ghost
Copy link

ghost commented Aug 26, 2015

The current java api provides no compile-time safety for api call parameters. Neither the names of the parameters nor the types being passed as values are checked at compile time. It would be beneficial to users of the API to have a fluent style api for Stripe api calls. For example:

    final Refund refund = 
        stripe.refund()
        .create(chargeId)
        .reverseTransfer(true)
        .metadata("reason", "refund due to cancellation")
        .idempotencyKey(stripeRefundNonce)
        .get();

This might seem like a lot of work, however the official Stripe API reference is structured so well that such an API can be generated directly from the HTML. In fact, I know it can be done because that's what I'm doing in my project. A little bit of Javascript, jQuery, and Mustache is all that's needed to create a fluent style api directly from the official reference documentation. Every time the API changes, the corresponding java code can be regenerated automatically. Additionally, because it comes directly from the documentation, we can also incorporate Javadoc:

    /**
     * A cursor for use in pagination. <code>ending_before</code> is an
     * object ID that defines your place in the list. For instance, if
     * you make a list request and receive 100 objects, starting with
     * <code>obj_bar</code>, your subsequent call can include
     * <code>ending_before=obj_bar</code> in order to fetch the previous
     * page of the list.
     */
    public final AllMethod endingBefore(final String endingBefore) {
        return set("ending_before", endingBefore);
    }

If this is something that should be in the official Stripe API then I can create a pull request for it, otherwise I can create a separate project that builds on top of stripe-java.

@kyleconroy
Copy link
Contributor

@hardtoe I'd be very interested see the entire SDK that you've generated from the docs. We actually have a completely representation of the API internally, so we could possibly generate something like this ourselves.

@Argoday
Copy link

Argoday commented Sep 17, 2015

+1 - the current design of this library is horribly non-object-oriented, this type of change would be much appreciated

@ghost
Copy link
Author

ghost commented Sep 17, 2015

I am happy to hear that the documentation has a nice internal representation. My code generation script today isn't able to extract parameter types and a few other things. Working directly from the internal representation will make your job much easier. I'll upload the code generation stuff as well as what the output looks like tonight.

@ghost ghost mentioned this issue Sep 17, 2015
@kyleconroy kyleconroy modified the milestone: Version 2 Sep 17, 2015
@kyleconroy
Copy link
Contributor

This has now been added to the roadmap. I'm closing the issue, but feel free to continue discussing here.

@kyleconroy kyleconroy reopened this Oct 2, 2015
@jxtps
Copy link

jxtps commented Jun 16, 2016

Any progress on this? Type safety would be extremely helpful, especially when upgrading to new API versions.

@brandur
Copy link
Contributor

brandur commented Jun 16, 2016

Any progress on this? Type safety would be extremely helpful, especially when upgrading to new API versions.

Alas, no :/ My apologies.

We totally understand the frustration here though, and would like to get this and other major bindings deficiencies fixed as soon as we can commit some resources.

@ghost
Copy link
Author

ghost commented Jun 16, 2016

Hey Guys, I don't have time to create this in a production-worthy fashion, but at least I can share what I did to generate the type-safe API I used:

https://gist.github.com/hardtoe/484a60ccb84ad2bbe829238e119be5e0

The gist is a bit of html and javascript I added to the stripe documentation page. If you open up the modified html file in a web browser it will output the Java code. Pretty janky, but it had worked well at the time. Might not work on the most recent html. In that case you can see the javascript integrated in the full stripe documentation page here...but it is slow in gist:

https://gist.github.com/hardtoe/f4d01b6863fcc1b86845144f94c720f4

@ghost
Copy link
Author

ghost commented Jun 16, 2016

Almost forgot, here's the generated Java code:

https://gist.github.com/hardtoe/35241100ae95faf9daef858be90c1c9e

And the base class it uses:

https://gist.github.com/hardtoe/0237dad6d7a4911a979da3668e83684d

@ghost
Copy link
Author

ghost commented Jun 16, 2016

And finally, a couple examples on how to use the API, otherwise it might be incomprehensible:

https://gist.github.com/hardtoe/c865ef2776db1b0bfea0df02164a9860

Basically it follows the fluent programming style in java. Required parameters are arguments in the factory function for building a request. Optional parameters are specified using methods on the builder object. JavaDoc is pulled in from the stripe documentation html.

@brandur
Copy link
Contributor

brandur commented Jun 18, 2016

@hardtoe Wow, thanks a lot for all the contributions! It looks like you've already done a lot of work here. It's going to take a bit of doing, but we're going to be trying to integrate something very close to what you already have here. This will help.

@mikesir87
Copy link

Just wanted to chime in too... I see this is on the roadmap, but haven't seen any progress made on the roadmap. Are there any design docs/thoughts about where the library should/will be going? I wouldn't mind helping pitch in, as long as there's at least an idea first. Thoughts?

@brandur
Copy link
Contributor

brandur commented Nov 3, 2016

Sorry, we have haven't had a lot of movement on this one so far :/

The final solution probably looks like a little something like resource parameter-specific structures, a little like what's in stripe-go:

https://github.com/stripe/stripe-go/blob/84484ce43b9b0edbdfde86a4c8f9d082df9e3638/account.go#L54,L65

But obviously backporting these for every endpoint is going to be a huge amount of work. We were hoping to get it done using some sort of code generations scheme, but haven't gotten there yet.

(Re-posted under correct account.)

@jxtps
Copy link

jxtps commented Apr 28, 2017

It's been 1.5+ years, was put on the roadmap for v2 and we're now on v4.

I realize that dynamic languages are all the rage, but statically typed folks need some love too ;)

@brandur-stripe
Copy link
Contributor

It's been 1.5+ years, was put on the roadmap for v2 and we're now on v4.

Just a minor pedantic note: we version semantically so the only thing a major bump means is that we've introduced something that's not backward compatible; it's not like we're packing new features in there or anything so I wouldn't read into it too much.

That said, I hear you. I'm not happy with the current state of things here. As remarked before, it's unfortunately a huge overhaul and we've got a lot of other things on our plate, but I expect to get to it at some point.

I realize that dynamic languages are all the rage, but statically typed folks need some love too ;)

Hah +1. Actually, I want to put static sets of accessors for parameters and responses into our dynamic languages as well when we can. It's just better.

@kjc-stripe
Copy link
Contributor

I've made a first pass generating value objects for each API method in #392. I'd love to hear what people think of this approach. I personally really like it.

@corrspt
Copy link

corrspt commented May 9, 2018

It has been almost 4 years since this issue has been open.

I understand it is not an easy task, but Stripe is known for an easy to use API and great documentation, but this Java library needs some serious love. Type-safety and discoverability are really great tools in the Java world. The lack of Java docs (with Examples) doesn't help.

Would love to see the Stripe team find some resources to improve this :)

@ob-stripe
Copy link
Contributor

Hi everyone. I know it's been a long time since this issue was opened, but I'm happy to report that as of stripe-java v9.0.0, the library finally has support for fully typed request parameters!

You can see an example of the new syntax in our migration guide here. Over the next few weeks, the examples on Stripe's site will also be updated to use the new syntax.

Thanks a lot for your patience. I'm closing the issue, but please do feel free to share your feedback.

@kyleconroy
Copy link
Contributor

@ob-stripe 🙌 Amazing job!

@ob-stripe
Copy link
Contributor

@kyleconroy ~all the credit goes to @mickjermsurawong-stripe 😀

@ErnestoGarciaGenesys
Copy link

ErnestoGarciaGenesys commented Sep 15, 2019

Hi, expanded objects are still requested by using strings, like in expandList.add("invoice.subscription"). It would be nice to add compile-time validation to expanded fields as well.

@ob-stripe
Copy link
Contributor

HI @ErnestoGarciaGenesys, thanks for the suggestion. We'd like to add this in the future, but nested expansions, list calls (which require a data. nesting level) and the maximum of 4 nesting levels make this difficult to implement this in the type system. That's not to say we'll never add this, but it's not being prioritized right now.

@titogarcia
Copy link

The maximum of 4 nested levels could be reached just by offering 1-parameter, 2-parameter, 3-parameter, 4-parameter versions of a method. (Just thinking off-the-bat).
It would be more problematic to statically check that getObject() can't be called unless the field was requested to be expanded before... :)

@ob-stripe
Copy link
Contributor

@titogarcia Do you mind opening a new issue for this? This way future conversation won't "spam" people who contributed to this old thread a long time ago. Thanks!

@stripe stripe locked as resolved and limited conversation to collaborators Sep 17, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests