Validate input in Golang easily

blov · · 486 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Most of the time I used to build REST API for different services. For this purpose, I need input/request validator badly. I was finding a validator like Laravel validation process, but it was not available in Golang. For this reason, I have built a new <a href="https://github.com/govalidator/validator">validator package</a> for Go.</p> <hr/>**评论:**<br/><br/>aimatt: <pre><p>I don&#39;t like that you pass strings in as the validation rules. It makes it weakly typed and you won&#39;t know about typos until runtime. </p> <p>Check out something like goconvey that uses interface{} to allow static rules passed in. </p></pre>skidooer: <pre><p>Honestly, I think Upspin gets <a href="https://github.com/upspin/upspin/tree/master/valid" rel="nofollow">validation right</a>. Straightforward and concise Go code, with no special magic.</p></pre>arp242: <pre><p>This is also why I don&#39;t like stuff that relies on struct tags.</p> <p>It&#39;s kind of difficult to 100% avoid passing any strings though; or if there is a way, I haven&#39;t found it :-)</p> <p>In <a href="https://github.com/teamwork/validate" rel="nofollow">the package I wrote</a> a while ago you need to use e.g. <code>v.Required(&#34;firstName&#34;, customer.FirstName)</code>; the <code>firstName</code> is used for the error output only. It&#39;s hard to avoid this; reflection is a possibility but first of all reflection, and secondly it would limit the input to structs. <code>v.Required(&#34;firstName&#34;, firstName)</code> would not be possible.</p> <p>It&#39;s a bit redundant, but not too much, and at least the string value is close to the actually typed value (usually on the same line), so typos should be easier to avoid. Also, typos don&#39;t prevent anything from working, it would just make the errors look wrong (or in our case, not correctly highlight the form input in the frontend JS code). This can still be very confusing, but I don&#39;t know if any good way to avoid it...</p> <p>Also, the code in my package is ridiculously simple and avoids a lot of the complexity I&#39;ve seen in some other packages (like the OP&#39;s package).</p></pre>aimatt: <pre><p>In a typical web application, reflection won&#39;t add enough performance overhead to matter</p></pre>arp242: <pre><p>I&#39;m not concerned about performance per se, it&#39;s more that reflection can make code hard to understand.</p> <p>Point in case: this morning I actually updated some code which used a lot of reflection, and even though it turned out to be a simple 2-line change it took me 30 minutes.</p></pre>paul2048: <pre><blockquote> <p>In a typical web application, reflection won&#39;t add enough performance overhead to matter</p> </blockquote> <p>it has to be benchmarked. Reflection can absolutely slow down a routine by 100%,1,000%, 10,000% or even more. Reflection also hinders readability considerably.</p></pre>aimatt: <pre><p>I think that if your application is hinging on 10uS of validation turning into 100uS of latency, then you are probably not the target audience. </p> <p>On the other side of the coin, 10x degradation in performance is frequently more desirable than a panic at runtime crashing the whole goroutine (or more) due to mis-spelling a validation rule before build time that went unnoticed. </p></pre>zemo: <pre><p>you can&#39;t really confirm the validity of the validators at compile time anyway, because any validation system would itself require some form of validation. E.g. this constraint: </p> <p><code>&#34;email&#34;: []string{&#34;required&#34;, &#34;min:4&#34;, &#34;max:20&#34;, &#34;email&#34;},</code> </p> <p>We could model it in a typesafe fashion. Let&#39;s say we have some interface <code>valid.Validator</code> that validates a value, <code>valid.All</code> is a <code>[]valid.Validator</code> that satisfies <code>valid.Validator</code> and requires every contained validator to validate a value, <code>valid.MinLength(n)</code> is a function that, given an int, returns a string validator requiring that the provided value is a string over length <code>n</code>, we could write the above constraint in a type safe fashion as follows: </p> <p><code>&#34;email&#34;: valid.All{valid.Required, valid.MinLength(4), valid.MaxLength(20)}</code></p> <p>That&#39;s all well and good, but the safety here is purely imagined, since even if you have types, you could have invalid constraints. For example, <code>valid.MaxLength(-20)}</code> makes no sense because you can&#39;t have a max length of a string be -20. </p> <p>It gets worse when you are composing the validators, since you could potentially create an entirely disjoint union of validators. For example, <code>valid.All{valid.MinLength(10), valid.MaxLength(9)}</code> would yield a validator that has no passing values. No matter how you cut it, you need to perform some type of evaluation to determine the legitimacy of your validators anyway.</p></pre>aimatt: <pre><p>But at least if I spelled &#39;valid.MinLength&#39; as &#39;valid.MinLen&#39; it wouldn&#39;t compile. </p></pre>Sythe2o0: <pre><p>You&#39;re correct, but getting rid of some forms of error through static typing is always an improvement for catching errors ahead of time. </p></pre>nashkara: <pre><p>Why not use something like JSON Schema?</p> <p>Honest question as I haven&#39;t gotten much into the spec or implementations in go.</p></pre>Xargin-cc: <pre><p>why not use goplayground/validator</p></pre>paul2048: <pre><blockquote> <p>For this reason, I have built a new validator package for Go.</p> </blockquote> <p>How do you write a rule so that given a username, that username is unique in a remote database? </p></pre>thedevsaddam: <pre><p>Please add a custom rule to check username <a href="https://pastebin.com/yGhJu8JP" rel="nofollow">see here</a></p></pre>SeerUD: <pre><p>Just a heads up, the word you&#39;re after instead of &#34;encouraged&#34; is &#34;inspired&#34;. You might normally say something like &#34;heavily inspired by&#34;.</p> <p>It looks pretty comprehensive though, so nice job with that - there&#39;s some good validations in there. Could you make it more generally re-usable though? i.e. maybe make it support validating things other than HTTP requests?</p></pre>thedevsaddam: <pre><p>Thank you, I have updated the word. It&#39;s a request validator so it&#39;s main focus is to validate the HTTP requests. If you need struct/map validator then you should use go-playground/validator</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

486 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传