Defined required fields in proto3 - protocol-buffers

I am using protobuf with version3 in Php. Below is my proto file
syntax ="proto3";
package message.events.user.v1;
message UserWasActivatedMessage {
int32 userId = 1 ;
string eventType = 2;
}
This is my proto file and whenever I do not set any user or event proto is automatically setting them up with a default value which I do not want, now I want user to explicitly define every value whenever they send a message as this will reduce the chance of not defining any value

This is a "feature" of protocol buffers and cannot be overriden using the standard SDKs. See:
https://developers.google.com/protocol-buffers/docs/proto3#default
I assume the requirement of having default values is a result of the schemaless nature of on-the-wire messages, where all fields must be included and there being no way to specify a value as nil.
Yes, there's a difference in meaning between nil and default but you can't reflect that in protocol buffers.

Related

gRPC Proto Buff URL/URI type

Is there a way to use Url or Uri data type inside a message of gRPC? And if not what is the best way to do this?
I am using gRPC and Protocol Buffers for this and I run a backend go app to trigger popup notifications that display in my Flutter app. The notification has a link that takes the user to a webpage when clicked on in my Flutter app.
Right now I am using a String for this, like so:
message NotificationResponse{
string title = 1;
string url = 2;
}
I can't seem to find a way to use Url/Uri as a type. Is there such a thing?
Storing in a string is a totally viable solution. But if you would like to reduce the payload size a little and make the instantiation little bit safer, you could remove the schema part of the url (eg: https://).
To do that you could do the following:
message Url {
enum Schema {
UNSPECIFIED = 0;
HTTP = 1;
HTTPS = 2;
// more if needed
}
Schema schema = 1;
string rest = 2;
}
and then you can use it in your message like this:
message NotificationResponse {
string title = 1;
Url url = 2;
}
This would exclude these non necessary character in the string and reduce the payload size (remove http(s) and ://). Enum are serialized more efficiently than string.
This would make instantiation safer because you can restrict at least the schema that you and other developers can use (in my example, no ftp or even restrict to only https for security).
That has one inconvenience though. You will have to concatenate that back in your client code, but in my opinion this is worth the effort since the concatenation is pretty trivial (change enum value to is text value and add ://).
Note: doing the same enum trick for Domain Name (.com, .net, ...) would not be as trivial and would force you to store the path and the host in different field (not worth it since it increase payload).
Let me know if you need more help.

How would you explain this type of syntax (casting)?

Looking at the source code c.Organizations = (*OrganizationsService)(&c.common) from https://github.com/google/go-github/blob/master/github/github.go#L283, in describing this bit of code with proper terminology, would you describe it as follows:
The Organizations field of variable c is set to the address of c.common casted to a pointer receiver value of OrganizationsService.
Or am I missing a bit of nuance when describing this?
Below are some relevant bits of source code that show where the variables are being defined.
// A Client manages communication with the GitHub API.
type Client struct {
clientMu sync.Mutex // clientMu protects the client during calls that modify the CheckRedirect func.
client *http.Client // HTTP client used to communicate with the API.
// Base URL for API requests. Defaults to the public GitHub API, but can be
// set to a domain endpoint to use with GitHub Enterprise. BaseURL should
// always be specified with a trailing slash.
BaseURL *url.URL
// Base URL for uploading files.
UploadURL *url.URL
// User agent used when communicating with the GitHub API.
UserAgent string
rateMu sync.Mutex
rateLimits [categories]Rate // Rate limits for the client as determined by the most recent API calls.
common service // Reuse a single struct instead of allocating one for each service on the heap.
// Services used for talking to different parts of the GitHub API.
Actions *ActionsService
Activity *ActivityService
Admin *AdminService
Apps *AppsService
Authorizations *AuthorizationsService
Checks *ChecksService
CodeScanning *CodeScanningService
Enterprise *EnterpriseService
Gists *GistsService
Git *GitService
Gitignores *GitignoresService
Interactions *InteractionsService
IssueImport *IssueImportService
Issues *IssuesService
Licenses *LicensesService
Marketplace *MarketplaceService
Migrations *MigrationService
Organizations *OrganizationsService
Projects *ProjectsService
PullRequests *PullRequestsService
Reactions *ReactionsService
Repositories *RepositoriesService
Search *SearchService
Teams *TeamsService
Users *UsersService
}
type service struct {
client *Client
}
The Organizations field of variable c is set to the address of c.common casted to a pointer receiver value of OrganizationsService.
This is close, but I'd make a few changes.
First:
casted
The operation being done here, according to official Go terminology, is a "conversion" not a cast.
Second:
c is set to the address of c.common...
While & is the "addressing" operator, the value that it results in is a pointer value. The literal contents of that value is the address. It's not incorrect to refer to addresses, but while analyzing syntax and structure, we would probably rather refer to values at the high level, rather than the contents of them.
Third:
pointer receiver value of...
The word "receiver" in Go refers to the receiver value in method call or method declaration, e.g.
func (v *Value) Method() {
}
Here v is the receiver, and it's type does happen to be a pointer type, but it doesn't have to be.
func (v Value) Method() {
}
This is also valid (though may have different and unintended effects compared to the first version). Regardless, the value in your question is not a receiver in any sense.
With the adjustments:
The Organizations field of variable c is set to the pointer to c.common converted to a pointer value to the OrganizationsService type.
Even still, we could restructure the sentence a bit so it is more similar to the order of operations as they happen in the program. It may seem natural to analyze things from left to right, but this is rarely the most comprehensible expression of code.
Here's an explanation that is, in my opinion, more natural.
The pointer to c's "common" field is converted to a pointer to OrganizationsService, and then assigned to c's "Organizations" field.

(Swift) Initializer for conditional binding must have Optional type, not 'AVAudioInputNode'

I am trying to create a speech to text function and I am getting the error:
Initializer for conditional binding must have Optional type, not 'AVAudioInputNode'
guard let inputNode = audioEngine.inputNode else {
fatalError("Audio engine has no input node")
}
AVAudioEngine's inputNode property is not an optional. The Audio Engine creates a singleton on demand when inputNode is first accessed. It cannot be nil and because of that the guard does not make sense.
So, just remove the guard and use audioEngine.inputNode as it is. It cannot be nil.
You still have to make sure that the inputNode is connected to something before using it:
Check the input format of input node (specifically, the hardware
format) for a non-zero sample rate and channel count to see if input
is enabled.
(from Apple's Documentation)

Creating an instance of a structure with unexported sub-structures in Go

I am trying to manually create an instance of the type ReactionAddedEvent given here, in nlopes' Go Slack library. However, the sub-type reactionItem is unexported, which leads me to receive the error ./bot_test.go:111: cannot refer to unexported name slack.reactionItem when trying to instantiate the object.
Here is my code:
m := &slack.ReactionAddedEvent{
Item: &slack.reactionItem{
File: &slack.File{
Preview: "Test",
URLPrivate: "http://google.com",
},
},
Reaction: "white_check_mark",
}
When I remove the identifier &slack.reactionItem from line 2 in that snippet, I get instead the error: ./bot_test.go:112: missing type in composite literal, obviously.
Is there any way for me to instantiate an object of this type with the parameters I need?
First, if slack here refers to the nlopes library, the slack.ReactionAddedEvent structure's Item field is not a pointer, so you can't store an address of a slack.reactionItem struct into that field anyway. Second, the File field of slack.reactionItem is a string, not a structure.
Third, even if the above isn't/weren't the case, if the types are not exported, but the fields themselves are, you can't assemble the structure in a single literal. Instead, you'll have to manually set those fields after creating the structure variable:
m := &slack.ReactionAddedEvent{Reaction: "white_check_mark"}
m.Item.File.Preview = "Test"
m.Item.File.URLPrivate = "http://google.com"
But again, if you're using the nlopes library, that won't work because the File field isn't actually a structure:
https://github.com/nlopes/slack/blob/master/websocket_reactions.go
And fourth, if the type isn't exported, that's probably a good sign that you shouldn't be manipulating objects of that type. In this case, in the nlopes library, those structures are only intended to be used for unmarshalling and then handling events from JSON messages.

Thrift Default Enum values

Using Apache Thrift and generating code in Java, I'm trying to figure if there is a way to have one of the enumerations be returned as default.
For e.g using the following definition:
enum STATE {
UNKNOWN,
AVAILABLE,
UNAVAILABLE
}
I want UNKNOWN to be returned as the default and not a NULL value so that additions to the enum do not affect existing clients.
Is it possible to do that? What are the other options available in this case?
I'm not sure about the part "returned as default" since there is no such thing as a default return value. What may solve your issue could be sth. like:
struct ReturnedValues
{
1: STATE state = UNKNOWN
}
Otherwise you should explain your case.

Resources