Comments (8)
Here are the debugging steps in order "neglecting few non-important ones":
Turns out that something I could catch for the first time which should be taken into account to enhance the performance & resource utilization further. As calling functions that do nothing except calling other functions without doing real job should be really avoidable specially in Go. "Due to its initial small stack size per routine, and to simplify the stack trace minimizing the transmitted meta data!"
from gin.
@ahmadSaeedGoda Hi, thanks for your reply and the debugging screenshots. That gives some nice information on how the Bind functionality works.
However, I did not say in my question that the omitempty
tag was misbehaving; actually, I am not reporting a bug at all in this issue. Rather, I am simply asking "Is there a combination of tags that would make this possible with Gin?". If the omitempty tag will still bind empty user-provided values to struct fields instead of using the default form value, then my question is simply whether there is some other tag I could use so that whether the user provides no value or an empty value, the default will still kick in and override the user's input.
If that's not possible, then could we add this functionality somehow, such as adding a form tag defaultIfEmpty=
so that the default kicks in whether the user provides no input or empty input?
EDIT: It turns out someone seems to have mentioned this same issue in 2019 if I'm not mistaken
from gin.
@takanuva15 Currently you can only handle the assignment problem manually, which is the least costly for you
The question you raised, and I thought about it a little bit, is that the logical tree will converge to the point where the incoming value is null, and the default value, the default value is enabled.
The scope of the impact of modifying gin's underlying code is difficult to estimate.
Lines 136 to 166 in 3cb3067
The legacy code and github.com/go-playground/validator validation framework don't mix well.
gin/binding/form_mapping_test.go
Lines 70 to 82 in 3cb3067
If you have a strong idea, you are welcome to submit a PR here
from gin.
@takanuva15 That's a good point. But shall we agree that "default value" "as the name suggests" is meant to be applied whenever the value passed is null or empty?
Meaning absent or provided but zero value..
Isn't this the meaning of default?
So talking about existing servers that assume when client provide empty value, the default value should not be applied. Why in the first place they specify a default value?
Someone might say, they specify the default value to be applied only when value is not sent/passed around (== nil/null). Okay and what if empty? doesn't empty means that the client wants it to be just sent for some cases like mandatory fields required by the server? Then server can decide how to populate it, either as empty or specify a default value. Both cases are handled here with my PR proposed change. Because if the server developer or maintainer decide to set default value within struct tags, it makes sense to be applied on empty and null values, here the framework usage is clear. Otherwise, if the server coder decides that there should be no default value applied, then empty is gonna be handled as empty.
Framework is to take care of providing user(developer) some way to determine how the value should be validated.
Validation must be conducted as per user/developer instructions via code.
When user/developer require a field to be provided/passed/sent by client request, only 2 options/scenarios here are possible. Either client provide value to be set for this field, or empty value. When dev state default, it has to be set for empty because the field is required in the first place! Means that default is only meant for empty values because there can be only values or empty values in this scenario of a required field. Not possible to have nil or absent field value. It's either empty or has value. Then default value has only one purpose, which is to replace empty values provided by the client.
So your suggestion can't be relevant for the above scenario I think, can it?
Second scenario is when field is optional (not required by the server), in such a case client can either provide value, empty value, or not send it within the request at all. Here 3 options available. When developer say default value is blabla
. They must mean that this value is to be set for the null & empty cases altogether. Otherwise, the framework must provide functionality or option for developers to state a default value for null and another for empty (does not make sense for me). I just assumed that the framework will treat both as no value, then check if default stated and set it as is (whether stated or not stated it's gonna be set).
If default has been stated by dev, it's gonna replace empty or null values. If not stated, the default value is now an empty value, that will replace the empty value provided by client. So nothing happens, and the empty value provided will remain empty as it's replaced by empty which is equal.
I must admit I like your way of thinking, but just wanted to clarify for you my intention & reasoning behind appending that peace of code. So let's distill all the cases as follows in bullet points:
1. Required field:
- Non-empty Value provided by client: Value will be set no matter default value specified or not.
- Empty Value provided by client: If default value specified it's gonna be set. If no default value specified, means the default value is empty or zero value for string, which is the data type the framework uses already for the default upfront before setting the appropriate type later on. So my proposed change will fill the field with default whether specified with val or empty. Empty default val that will replace empty provided val means no impact.
2. Optional field:
- Not provided at all by client: Here framework checks for default value and set it. No issue.
- Provided as empty by client: Here framework checks for the field if passed, then it finds it available "but carries empty val", so framework will set field's value as provided "which is empty". After that it will check it if empty, it gonna check the default value, if default exists will replace the value of the field. If not exists, means default is empty, so no problem of replacing empty value provided with empty value for default. Has no impact but still achieving the goal.
- Provided with non-empty value by client: Here my proposed snippet has no impact also.
Hopefully I could make it a bit clearer, and kindly take a look at the function that does all what I've tried to explain above:
Lines 217 to 270 in 3cb3067
It explains everything I listed here in a very concise manner. First checks if field is passed by client "set as key in the form map" and default value exists, if one of them isn't true the function stops execution and returns 🤷♂️
then falls down to default case in the switch
statement (as in our case the field isn't slice nor array), checks the previous condition separately. If not ok (means field isn't passed at all as not set into the form map parameter/argument) it sets default as-is, since it doesn't matter there exists default value or not, the field is to be filled with it whether has default or empty string (""). After that function checks the availability of provided value, again it fills the field with it as-is (no matter empty or non-empty). Here my addendum/supplement comes into play to check once again if val
of the field is still empty (which means the value is provided but empty) so the default will be set again no matter it has value specified as default or not specified so it is empty.
All of this has no contradiction with current implementation and all the responsibility falls entirely on the developers' shoulder to know what they are doing logically. Additionally, all the test cases pass BTW, which means my change shouldn't conflict with any other cases already available and provided by the current version of the framework. Moreover, I've appended some tests to already available case, along with 2 of mine to cover my introduced tiny change.
It's confusing a bit by nature, and I highly appreciate your excellent point & your feedback. Just wanted to share with you my thoughts about what's already the case provided by the current implementation that doesn't allow for empty fields sent, to be saved empty with the existence of default value.
No breaking change IMHO.
from gin.
But I think when you pass it like: curl 'http://localhost:9000/hello?name='
it means an empty string for the param value "the zero value for type string".
When not passed at all, its value will be nil
, means value is absent. Then, and only then, the validation should take place and put "myDefault" instead.
Anyway, I am debugging it to find out some helpful/useful info to share once available. It should be something relevant to the zero value validation case. I do not think it is a bug so far. And I see it as intuitive and idiomatic behavior TBH.
@takanuva15
from gin.
Kindly check the PR to lemme know if any!
Cheers,
from gin.
@ahmadSaeedGoda Hi, thanks for your reply and the debugging screenshots. That gives some nice information on how the Bind functionality works.
However, I did not say in my question that the
omitempty
tag was misbehaving; actually, I am not reporting a bug at all in this issue. Rather, I am simply asking "Is there a combination of tags that would make this possible with Gin?". If the omitempty tag will still bind empty user-provided values to struct fields instead of using the default form value, then my question is simply whether there is some other tag I could use so that whether the user provides no value or an empty value, the default will still kick in and override the user's input.If that's not possible, then could we add this functionality somehow, such as adding a form tag
defaultIfEmpty=
so that the default kicks in whether the user provides no input or empty input?EDIT: It turns out someone seems to have mentioned this same issue in 2019 if I'm not mistaken
@takanuva15 with the proposed PR You can have the default to kick in whether the user provides no value or not sent the field at all. I've decided that it should be done with no need for a new form tag such as defaultIfEmpty=
as it's a basic assumption that the default value specified via code should kick in for any empty value no matter provided as empty or not sent in the first place.
Hopefully that makes sense,
Awaiting approval from maintainers.
from gin.
I was gonna say that the way your PR is implemented, it's a breaking change to existing servers that assume the default value is not applied if the client sends an empty value. Looks like your PR got merged anyways though and it's set for v1.11, so whatever lol
from gin.
Related Issues (20)
- custom time.Time type can not use ShoudBindQuery get a value ,error : invalid character '-' after top-level value HOT 3
- [Bug] UnescapePathValues = false still unescapes path values
- [Bug] infinite redirect with RedirectFixedPath HOT 2
- [Bug] EOF when using ShouldBindJSON HOT 6
- can suport domain router? like github.com/gorilla/mux HOT 4
- time param with timezome in Get method ShouldBindQuery parse error HOT 3
- dare you add a detailed API doc? HOT 5
- Is Gin Context violating the golang context styleguide? HOT 3
- Overwrite `JSONRender` similar to `HTMLRender` HOT 1
- msgpack incorrectly encoding unsigned integers HOT 2
- RecoveryWithWriter takes mulitple RecoveryFuncs but only applies the first HOT 3
- Different 404 handler for different group HOT 4
- Interrupt-drop-cancel request by user
- Automatically generate documents HOT 3
- LogFormatterParams.Body reading failed
- $ go run example.go HOT 6
- About bind parse HOT 2
- Gin is rendering the wrong template HOT 3
- goroutine leak
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from gin.