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

Interest in type-checked grape? #2343

Open
aleksclark opened this issue Jul 26, 2023 · 4 comments
Open

Interest in type-checked grape? #2343

aleksclark opened this issue Jul 26, 2023 · 4 comments

Comments

@aleksclark
Copy link

Heyo,

So I've been using grape extensively for the past few years, and with RBS and steep/sorbet progressing, I wondered what the interest would be in adding type-checking to grape.

In a sense, the params parsing brings maybe 30% of the benefits of types to a grape API, and provides a solid target for generating OpenAPI/Swagger. My thought would be to implement something like the following:

  1. either move params definition into RBS, or infer types from the existing DSL, preferably the latter, with the result that you get type checking/hinting/completion in your api endpoint method, e.g. params.username -> String
  2. do essentially the same thing for endpoint method returns, although those are currently just "documented" for OpenAPI purposes, but basically you should get an error if you return my_obj.to_json instead of my_obj when the endpoint is supposed to return an instance of my_obj.class
  3. Bring grape-entity along for the ride - add typing to its DSL
  4. once the above are complete, it should be possible to generate OpenAPI specs from the types themselves instead of from developer-provided doc strings/annotations, and use static analysis to ensure a given API conforms to the spec

This is obviously a fairly complex task, so my first question is, is this something people would find useful? It would eliminate a whole category of tests and bugs involved in ensuring backend talks to frontend properly, but it would also add a non-trivial amount of friction.

My second question is, where does this belong? I think monkey-patching/extending grape, grape-entity, and grape-swagger in a new gem should be possible, but I could also see an argument for forking grape and adding this functionality directly, or for trying to make it a first-class, opt-in feature of mainline grape.

Thanks for your thoughts!

@dblock
Copy link
Member

dblock commented Jul 26, 2023

I think it's a great idea, and I think you're on the right track for params. What do you think about extracting validation into a separate library (everything in https://github.com/ruby-grape/grape/tree/master/lib/grape/validations) in a way that can be swapped? You could then make a grape-params library that implements our current state, and an RBS-enabled library called grape-params-rbs. I think grape-entity and friends can follow the same model, except that I would just fork those into RBS-enabled implementations.

All that said, I would definitely POC the work by brute-forcing it in a fork first ;)

@Caleb-T-Owens
Copy link

I would love to see this happen

@olivier-thatch
Copy link

Only tangentially related to the ask in the first post, but if anyone is interested in using Grape in a Sorbet-typechecked project, you'll probably find the grape_sorbet gem helpful.

For now the gem is mostly focused on making it possible to use Grape without having to opt out of typechecking entirely with # typed: false or littering the code with T.unsafe.

In theory, it should be possible to achieve something close to what the first post suggests by defining Sorbet typed structs to hold parameters and augmenting Grape's params DSL to accept a T::Struct, but I haven't explored this at all and I'm not sure how you'd handle custom validators with this approach.

@Caleb-T-Owens
Copy link

Whoa! Thank you for your contributions to the space @olivier-thatch. I'll have to check this out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants