I have this input type and I would like to add a default Value to one of the fields. I want to add 0 to the value field inside the ExampleInput.
type ExampleType {
value: Int
another: String
}
type Mutation {
example(input: ExampleInput): ExampleType
}
input ExampleInput {
value: Int
another: String
}
Any ideas?
It looks like the grammar allows default values on input object types, so you can declare
input ExampleInput {
value: Int = 0
another: String
isAvailable: Boolean = false
}
The spec is clear that default values exist and explains how they get used (first bullet under "Input Coercion").
(Whether any specific tooling supports this is probably variable: graphql.org had an informal version of the IDL for quite a while before it was actually in the spec, and I have the impression some libraries haven't caught up to the released spec yet.)
Related
In protobuf version 3 required and optional keywords first have been removed, since required often caused problems protobuf issue 2497.
Recently the 'optional' keyword has been reintroduced protobuf v3.15.0.
Is it possible to simply add the optional keyword to an existing message?
I.e. change
message Test {
int32 int32_value = 1;
string text_value = 2;
}
to
message Test {
optional int32 int32_value = 1;
optional string text_value = 2;
}
Or will this break the binary format?
non-optional primitive types in protobuf don't accept null-values and normally also map to non-nullable types like int in Java or C#.
But this doesn't mean, that the field is always included in the binary representation.
In fact, if a field contains the default value for the corresponding type the field is omitted in the binary representation.
Thus the following message
message Test {
int32 int32_value = 1;
string text_value = 2;
}
Test test = new Test();
byte[] buffer = test.ToByteArray();
gets serialized to buffer containing an empty byte[].
So missing fields default to default values without the use of optional.
If the optional keyword is changing the behaviour for missing fields in the binary format and for default values specified:
Missing fields indicate the field has not been specified and indicate null. Setting default values will not result in an empty byte[] but in the default values being serialized.
Thus changing a primitive field to optional won't break the format, but will change the semantics:
All fields of old messages that have been specified with the default value will be interpreted as null. Other values are not affected.
The same for optional being removed from a field:
The api won't break, but change semantics. Unspecified fields will then default to default values for the corresponding type.
Consider the following json representation of an object
{
"format": "0.0.1",
"has_impl": true,
"mtv_1b": 1,
"mtv_1c": "h",
"ktc_12": true,
"ktc_zz": true,
}
The first two format and has_impl fields are known. In addition, the object may have arbitrary number of mtv_XX and ktc_XX like fields.
Is such an object representable in proto3 and how would you go at it ?
The following could be an obvious starting point. Are there a combination of oneOf, WellKnownTypes that could be used here ?
message MyObject {
string format = 0;
bool has_impl = 1;
// Is there anything that can go in here ?
....
}
Not directly. The closest you can do would be to have a Struct (which is a map<string, Value>, where Value is a oneof over common types), using struct.proto. Not quite the same, but allows the same ideas.
I am using protocol buffers defined like this:
message Index {
message albums {
repeated string name = 1;
}
map<string, albums> artists_albums= 1;
map<int32, albums> year_albums = 2;
}
It generates go code like this:
type Index struct {
ArtistsAlbums map[string]*IndexAlbums
YearAlbums map[int32]*IndexAlbums
}
How can I make it generate map values of type IndexAlbums instead of *IndexAlbums?
If you use gogoprotobuf then there is an extension that will allow that
map<string, albums> artists_albums = 1 [(gogoproto.nullable) = false];
With regular goprotobuf I don't believe there is a way.
nullable, if false, a field is generated without a pointer (see warning below).
Warning about nullable: According to the Protocol
Buffer specification, you should be able to tell whether a field is
set or unset. With the option nullable=false this feature is lost,
since your non-nullable fields will always be set. It can be seen as a
layer on top of Protocol Buffers, where before and after marshalling
all non-nullable fields are set and they cannot be unset.
I'm wondering if it is possible to use Google Protocol Buffers' enum constants as a field number of other messages, like
enum Code {
FOO = 100;
BAR = 101;
}
message Message {
required string foo = FOO;
}
This code doesn't work because FOO's type is enum Code and only a number can be used as a field number.
I am trying to build polymorphic message definitions like this animal example, that defines Cat = 1; in enum Type and required Cat animal = 100; as a unique extension number.
I thought it'd be nice to do
message Message {
required string foo = FOO.value;
}
, so that I can ensure the uniqueness of the extension field number without introducing another magic number.
So the question: is it possible to refer an enum's integer value in the protocol buffer language?
No, there is no way to do this. Sorry.
BTW, two enumerants of the same enum type can actually have the same numeric value, so defining these values in an enum does not actually ensure uniqueness.
I have class that have properties IsMacro, Value, Visible, DataType and one method GetResolvedValue. I dont know what to test. I do some math and I figure out that there is over 800 possible outputs for that method.
enum DataTypeEnum:
Bool,
String,
DateTime,
Integer,
LongInteger,
Decimal,
...
class Macro
property bool IsMacro;
property string Value;
property bool Visible;
property DataTypeEnum DataType;
function GetResolvedValue(Resolver) {
string value = Value;
if (IsMacro && Visilbe) {
value = Resolver.resolve(value);
}
switch (DataType){
case String:
// returns value if is string e.g.: "text"
// othervise returns empty string
case Bool:
// returns value if is bool string e.g.: "true"
// othervise returns empty string
case DateTime:
// returns value if is DateTime string e.g.: "2/2/2010"
// othervise returns empty string
...
}
}
So it must always return string with value that is valid for associated datatype or empty string.
With this code there is a lot of combinations and I dont know how to test it. Shoud I test all posible solutions?
Listen to your tests!
Even now, before even being written, your tests tell you that this method massively violates the SRP and needs to be refactored.
You should probably extract a whole hierarchy of classes from this one method.