4

My question is very similar to the question Default arguments with default values in Thrift Python client which was never completely resolved (one answer was a guess and the other was very hard to understand).

The question is, can you have a default parameter for service method without resorting to creating a struct for every method that needs one. I have the following Java service that I'd like to wrap with a Thrift handler

class MyService {
    public void foo(){ foo(false); } 
    public void foo(boolean someAdvancedFeature){...}
}

so I'd like to create the Thrift IDL

service MyServiceThrift {
    void foo(),
    void foo(1:bool),
}

but that is not valid as you can't have 2 methods named foo. So I tried

service MyServiceThrift {
    void foo(1:optional bool someAdvancedFeature = false)
}

but I get a parse error saying Cannot use reserved language keyword: "false" So I though well maybe I could just make it optional

service MyServiceThrift {
    void foo(1: optional bool someAdvancedFeature)
}

but I get the warning optional keyword is ignored in argument lists., which in hindsight makes some sense as it's just creating creating interfaces.

So is the only way to do this to create a new struct for every single method that takes an optional parameter? (Yes, you could re-use the struct for some methods, but I'd need one for every permutation of parameters, plus that'd break things down the road if one method added a parameter and the others didn't). It seems silly to make the users create a (potentially empty) class just to pass parameters to a method, and I really don't like the idea of having to generate/maintain a separate class for every single method in my services. Am I missing something?

Community
  • 1
  • 1
FuriousGeorge
  • 4,561
  • 5
  • 29
  • 52
  • Even though it is a year later, but it seems this boolean default value is not documented anywhere, and I learnt it the hard way. The (default) value of a boolean in a thrift struct is 0 or 1, instead of false or true. So in the thrift it should be "bool someAdvancedFeature = 0" – digit plumber Jan 23 '15 at 18:36

1 Answers1

1

That's a really good question, because technically the struct is already there - behind the scenes. I'm afraid, however, that the behaviour is as you describe and - at least currently - there is no other way other than maybe some workaround like that:

enum TriState {
   Unused = 0
   Yes = 1
   No = 2
}

service Foobar {
  void DoIt( 1: TriState someAdvancedFeature)
  void Ints( 1: set<byte> usedArgs, 2: i32 value, 3: string foobarbaz)
}
JensG
  • 13,148
  • 4
  • 45
  • 55
  • Eh, that feels dirty at best, and what happens when you need something like a default value for an `i32 timeout` or some sort of complex object? – FuriousGeorge Jan 13 '14 at 22:33
  • Hmmm, I guess i could define some constants like DEFAULT_BOOLEAN, DEFAULT_I32, DEFAULT_OBJECT etc, and pass those in. Then in my handler I could check if they passed in the Default value and then convert as need be. It'd all be contained in the one constants class and it wouldn't be TOO cumbersome. The only real downside is it wouldn't work for methods were the marker values could be legit parameters – FuriousGeorge Jan 13 '14 at 22:41
  • 3
    I didn't say it would be nice. – JensG Jan 13 '14 at 22:42