Skip to content
This repository has been archived by the owner on Mar 16, 2024. It is now read-only.

Code generation using Stripe OpenAPI #5

Open
dariusc93 opened this issue May 18, 2019 · 2 comments
Open

Code generation using Stripe OpenAPI #5

dariusc93 opened this issue May 18, 2019 · 2 comments
Labels
enhancement New feature or request

Comments

@dariusc93
Copy link
Member

The initial idea I had was to build a tool to parse a script and perform code generation for the API, but since I am now noticing that stripe have a open spec of their api, it may be best to parse and use that instead. Using spec3 from https://github.com/stripe/openapi (which would be more up to date), we could possibly perform some code generation to keep the API up to date.

@dariusc93 dariusc93 added the enhancement New feature or request label May 18, 2019
@dariusc93
Copy link
Member Author

More of an internal note:

OpenAPI, while it gives alot of insight on different things regarding the stripe api, it also open up abit more questions.

  1. Should there be two passes through the spec to gather information before generation of the code so there could be information at hand to work from? Could always load everything at runtime just once, but I do see instances where I would like to have information to work off of first before generating than to generate right out. Eg, listing all references, objects, etc. May not be necessary but having information doesnt hurt either.
  2. Should the components schemas reference be stored locally and map to be store in specific modules? Eg, linking #/components/schemas/card to src/resources/paymentmethods/cards.rs, etc.
  3. What would be the best way to handle anything introduced to the spec? Since stripe havent marked anything within it as "preview" or "beta", this do bring some questions on handling new api that may just be a preview.

If I wish to maintain current format and reduce possible breaking change, manual intervention might be needed in some areas (eg noting anything that is "preview" or "beta" or maybe even go as far as having it under a feature?). While we want to be able to generate the code, we also want to maintain stability as much as possible. May be best to implement test to make sure everything will continue to work as expected.

@dariusc93
Copy link
Member Author

dariusc93 commented Jun 8, 2019

While rewriting what I have, I decided that it would be best to stick with the current layout to make sure things are kept organized and to reduce breaking changes. In the process, I decided to have a mapping file that would be used to map specific objects to file within a resource directory. Eg mapping coupon to "src/resource/billing", etc. Currently, I am thinking of having it in this layout to define the structs that goes in which file under that directory

{
    "billing": {
        "path": "src/resources/billing",
        "resource": [
            {
                "coupons": {
                    "objects": [
                        {
                            "Coupon":{
                                "link_fields": [{
                                    "currency": "Currency",
                                    "duration": "Duration"
                                }]
                            }
                        },
                        {
                            "Duration": null
                        }, 
                        {
                            "CouponParam":{
                                "link_fields": [{
                                    "currency": "Currency",
                                    "duration": "Duration"
                                }]
                            }
                        },
                        {
                            "CouponListParam":{
                                "link_fields": [{
                                    "created": "RangeQuery"
                                }]
                            }
                        }
                    ]
                },
                "credit_notes": {
                    "objects": [
                        {
                            "CreditNotes":{
                                "link_fields": [{
                                    "currency": "Currency",
                                    "customer": "Customer",
                                    "invoice": "Invoice",
                                    "reason": "CreditNoteReason",
                                    "refund": "Refund",
                                    "type": "CreditNoteType"
                                }]
                            }
                        },
                        {
                            "CreditNoteReason": null
                        },
                        {
                            "CreditNoteStatus": null
                        },
                        {
                            "CreditNoteType": null
                        }, 
                        {
                            "CreditNoteParam":{
                                "link_fields": [{
                                    "reason": "CreditNoteReason"
                                }]
                            }
                        },
                        {
                            "CreditNoteListParam":{
                                "link_fields": null
                            }
                        }
                    ]
                }
            }
        ]
    },
    "checkout": null,
    "common": null,
    "connect": null,
    "core": null,
    "fraud": null,
    "issuing": null,
    "orders": null,
    "paymentmethods": null,
    "sigma": null,
    "terminal": null,
    "webhooks": null
}

Of course, this is subject to change as I may decide to write a script to run through stripe OpenAPI spec and map things accordingly (including having the ref contained in the spec to be mapped to the proper object) so when it come time to generating the code, it will output according to the format in the mapping and any new objects not here will likely go into a misc directory.

This still havent really resolved handling any preview or beta api calls, which may have to be marked manually and to be activated with a feature (due to the possibility of a breaking change since anything in preview is likely to change more often than anything outside of it).

Additional fields in the mapping file may be used to act as a way of renaming, however, that idea may be scratched out before publishing any code since some common things such as "type" would contain a prefix of what the type is used for. Eg, in CreditNote, "type" would be renamed to "credit_note_type", etc. Any custom enums we have (eg CardBrand), we may have the mapping file reference an enum since in the spec the brand doesnt reference one. Expandable fields do not need to be included in the file since the spec do contains which fields are expandable. Same with any objects or fields that are optional (or "nullable").

Ideally, once I get the time to finish the rewrite of the tool, the mapping file should be the only thing needing to be modified since it will be used as a reference.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant