-
Notifications
You must be signed in to change notification settings - Fork 509
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
ValidationService: Use joi for data validation #416
Comments
@WoH I realize I'm pretty absentee on this project right now. My main focus (outside of my actual job, lol) has been on a library that does what you're talking about, but in a more TypeScript-ish way and could serve as a drop in replacement for tsoa's existing validation. Once I actually release this library there will be more to talk about. What I'd like to avoid is adding runtime dependencies in the generated routes. |
@lukeautry sounds exciting, looking forward to that 👍 E: I'll close this, for now, thanks for the quick response. |
So what's the actual outcome of this? Are we going to use luke's library when it's finished? In my own usecase I use a custom template with my own 'validator' that links a type name to the appropriate (external) JSON-schema validator. Perhaps a solution could be adding a separate custom template for a validator implementation? That way you don't have to redefine the route generator if you just want a different runtime validation library, and we could still provide defaults for libraries like joi or the "vanilla" kind that's included now. |
@HoldYourWaffle you’ve mentioned this a couple of times in PRs and issues (here being the most recent). Let’s be clear: tsoa has always done validation. Validation is one of the goals of tsoa. You can say that you don’t think it should concern itself with validation, but that is one of it’s “critical path” features. So every design decision we make needs to factor in both swagger generation and runtime validation. For those who want to use a custom template to circumvent the default validation like you do, they will always be able to do that. But for the primary user of tsoa, they expect that the swagger documentation and the validation to work in the same manner. In other words, if the swagger doc describes that a query parameter is a date, then the runtime validation should throw if it’s not a date. |
You're focusing on the wrong thing here, I never said anything about "removing validation" or anything remotely like that, I just asked for the status on this and provided some input (including a possible solution) based on my own use-case. The built-in validation was very basic last time I checked (which is arguably pretty long ago now) and I can't imagine that the majority of users have it as their sole "validation layer". I'm definitely not saying that doing that is "wrong" or anything like that; it's just that, at least in my experience, validation requirements can get much more complex than what the built-in validator can provide. I personally think that it shouldn't try to be an all-in solution for that either, but that's not what I wanted to discuss. Yes, you can "remove" the built-in validator using custom templates, but that's not very convenient if you only want to customize validation. What I tried to propose was a system similar to custom router templates: a separate template for just the validator that can be freely mixed-and-matched with the router-template. We would of course still provide the default validator, and possibly even some additional ones like JOI (just like we do with router generation). I'd love to hear some actual feedback on this idea instead of being accused of going against the design goals of the project, as in my own humble opinion, "TSOA has always done validation" is not an argument against a more flexible system for the same validation. |
I think something might have gotten lost in translation, so I'd like to clarify why I specifically responded to the "all-in-one" aspect of tsoa. But first, let's break that comment down for the moment:
I was not saying that the past is written in stone. To be 100% clear, I am not advocating for status-quo. I believe that software can and always should improve to support the needs of it's users. What was trying to communicate is that tsoa's main benefit is that it is an all-in-one library for validation and the documentation of that validation. We can not deviate from that main benefit because we would simply be duplicating the many libraries that only do one of the things (validation or documentation).
No accusation is being made. However, you stated the following:
And then later you said:
As I hope to clarify below, the topic of whether or not tsoa should be in the business of runtime validation is a moot point because that is precisely the advertised value it brings to the NodeJS ecosystem. For anyone who does not want an "all-in-one" solution, they can use one of the multitude of alternative options available on the market that only do one of the things (validation or documentation). However, I sincerely hope that people choose to use Getting to the original topic of this issueHowever, since tsoa does two things it has some necessary bloat (although most of that bloat is stripped away at compile time). But for maintainers and contributors, it does appear (at first glance) to create some code that could be simplified by using an external library to do to one or both of the two things that tsoa does (swagger generation + swagger validation). That is why I believe @WoH submitted this design suggestion: He wanted to know if we would consider using a library to do the validation part for us. So when you say that you want
The outcome is that the creator of tsoa (Luke) said that he didn't want to bring in an external library. I (the current owner of tsoa) agree. I think it would be problematic to rely on an external library. However, I might be convinced once I see what Luke is working on. The creator of this issue (@WoH) thought that was a reasonable response and closed this issue. So the issue of using an external validator is closed for the time being. We can now move onto your separate topic of So, how would users get more flexible validationFirst off, I'm not sure why someone would want more flexible or powerful validation.
Before I became a tsoa maintainer, I was first a user of the library. At that time I was really impressed with the extensive validations and the flexible options that tsoa provides. So I would like to know more about what specific validations you can't accomplish with tsoa (before you answer, please consider that tsoa is all about "swagger compliant APIs" so it's validation should be limited to the shape of the data, not the business value of the data (which typically isn't documented in Swagger anyway since business issues are usually thrown as 422/UnprocessableEntity errors)).
I do, haha! Jokes aside, I was an enthusiastic user of tsoa before I became a maintainer. I was very impressed with the multitude of options that tsoa provides for validating the shape of the data. But if someone does find something to be missing in tsoa's feature set, then I would love for those people to create an issue so we can add that functionality to tsoa. On the topic of an external validator
My feedback is that it tsoa should not allow for custom validation. If an API wants to write custom validation, tsoa does not prevent them from doing so. You simply check the data inside of the tsoa route and throw a 400 error if the conditions you do not want have been found. Since tsoa's first goal is
Summary
Action items:
|
Upfront disclaimer: I'm pretty tired right now, I tried as best as I could to explain myself but I probably didn't catch everything. Just say the word if you need me to clarify some more :) I definitely think some things got lost in translation. Now on to the actual discussion again (do you want me to create a separate issue for this?). I currently use JSON-schema for my validation needs, most of the features I require are:
Some of those are very basic of course but I still included them because I have no idea if the default validator handles them already (I can't test it right now either). However, even if TSOA were to support all these validation features (and others I might want to use in the future), I'd still be more comfortable with using a battle-tested dedicated validation library, since such a library has validation (and therefore security) as it's primary goal and purpose. Another reason why I think TSOA shouldn't market itself as a validator is that it would be reinventing the wheel. There are already dozens of validation-oriented libraries out there, and a lot of them will probably be able to do a better job than TSOA ever could because they're specifically targeted towards validation (this is more prevalent for complicated validation scenario's). TSOA is also bound by whatever Swagger/OpenAPI supports, and those sadly don't support every kind of validation. I don't see a reason for "alienating" users that might not care about these specs by making it hard for them to fill in for their shortcomings.
I could validate the data manually inside the route, but doesn't that kind of defeat the point of automatic validation? Facilitating automatic validation (through code generation) is one of the two main reasons why I use TSOA, without it I'd basically be back to square one. I'm currently automatically validating incoming data with a custom router generation template, which works absolutely fine but it requires me to use a custom template for everything. This is inconvenient if I only want to switch out my validator and still keep the default router generation. It should also be noted that for this to work I needed to make some minor adjustments to the generation code, I'll see if I can create a PR for that sometime (it might not be 100% necessary).
I don't see how those two things are related, could you clarify?
I think my proposal (I wouldn't call it a 'framework') would massively increase maintainability, at least in the long run.
I didn't consider the 'framework' argument when I thought of this, although I wouldn't call it a framework. We'd of course have to "formalize" some kind of interface by which the router templates can communicate with the validator templates, but this shouldn't be too difficult or time consuming. If I'm not mistaken the only difference with how things are done now would be cross-router-type parameter retrieval, but I haven't really looked into this yet. To summarize: it's definitely not a trivial, oh-I-have-a-few-spare-minutes improvement, but I think it will massively help maintainability and developer experience in both the short and long term. |
Every validation you asked for is already in tsoa. |
Not sure if this was all added recently or if I was just blind, but I have now found the actual validation 'implementation' so to speak. I'm pretty sure I rummaged around in those files before when working of #445 and #451, no idea how I didn't manage to connect the dots. You didn't address my proposal though. Even though TSOA probably has all the features that I need right now, there's still a good chance that I may want to extend it in the future (for example by using JSON-schema). |
Since becoming more familiar with TSOA internals and therefore the ValidationService, I noticed there is a lot of custom validation logic involved.
Would it make sense to shift these responsibilities to another library and avoid duplicated efforts?
Maybe https://github.com/hapijs/joi is a good candidate to promote from dev to runtime dependency.
@lukeautry @dgreene1 @endor
The text was updated successfully, but these errors were encountered: