Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RPC response message usage definition #158

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion basics/error_model.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,36 @@ SPDX-FileType: DOCUMENTATION
SPDX-License-Identifier: Apache-2.0
----

uProtocol supports invoking operations on (remote) service providers by means of _Remote Procedure Calls_ (RPC).
In order to do so, a client uEntity (service consumer) sends an xref:uattributes.adoc#request-attributes[RPC Request message] to the service provider and waits for a corresponding xref:uattributes.adoc#response-attributes[RPC Response message] which conveys the outcome of the invocation of the operation.

uProtocol will follow Google's https://cloud.google.com/apis/design/errors[protocol-agnostic API error model] declared in up-core-api project in link:../up-core-api/uprotocol/v1/ustatus.proto[`ustatus.proto`] please refer to the proto for details about UStatus and UCode.
In general, an RPC can succeed or fail from the service consumer's point of view. In the former case, the response message contains the data/information that is the result of successfully processing the input data conveyed in the request message. In the latter case, the response message contains details regarding the reason why processing of the request message has failed.

uProtocol follows Google's https://cloud.google.com/apis/design/errors[protocol-agnostic API error model]. In particular, a service consumer *MUST* consider an RPC as _failed_ if the `commstatus` property contained in the xref:uattributes.adoc#response-attributes[response message attributes] has a value other than `OK`. In that case the response message's payload *MUST* be a serialized xref:../up-core-api/uprotocol/v1/ustatus.proto[UStatus] containing detail information about the reason for failure.

== Service Interface Design

uProtocol uses https://protobuf.dev/programming-guides/proto3/#services[Protobuf] for defining a service provider's operations. Based on the error model defined above, the _Protobuf Message_ defined/used as the response of an operation *SHOULD* only contain the data/information that represents the outcome of _successful_ execution of the operation.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
uProtocol uses https://protobuf.dev/programming-guides/proto3/#services[Protobuf] for defining a service provider's operations. Based on the error model defined above, the _Protobuf Message_ defined/used as the response of an operation *SHOULD* only contain the data/information that represents the outcome of _successful_ execution of the operation.
uProtocol uses https://protobuf.dev/programming-guides/proto3/#services[Protobuf] for defining a service provider's operations. Based on the error model defined above, the _Protobuf Message_ defined/used as the response of an operation *SHOULD* only contain the data/information that represents the outcome of _successful_ execution of the operation.
If a response message is not required to be returned by the method that was invoked, the rpc **SHOULD** declare that it returns `google.protobuf.Empty` that would mean there is no `UMessage.payload`.
Example: `rpc DoSomething(DoSomethingRequest) returns (google.protobuf.Empty) {}`

Copy link
Contributor Author

@sophokles73 sophokles73 May 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have just read through Google's Protobuf API best practices and wonder, if we should instead suggest to define custom empty messages?

WDYT? @stevenhartley

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is better that we define an empty per service like below and not a generic Empty message but I think that is what you mean:

rpc DoSomething(DoSomethingRequest) returns DoSomethingResponse {}

message DoSomethingRequest {
  // A bunch of crap
}

message DoSomethingResponse {}

I would need to check what would then be in the UMessage.payload, a serialized empty message I guess (doesn't hurt)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that is what I meant. IMHO this will also result in just an empty byte array, because the response message is defined exactly the same like google.protobuf.Empty.
I will update the spec accordingly ...


If an operation does not return any data/information on successful execution, the operation *SHOULD* use a dedicated empty response Message:

[example]
----
service HvacService {
rpc SetTemperature(SetTemperatureRequest) returns (SetTemperatureResponse);
}

message SetTemperatureRequest {
uint32 temperature = 1;
}

message SetTemperatureResponse {}
----

A service consumer invoking this operation will then receive a `UMessage` with an empty payload.

== Service Implementation

In case of _successful_ execution of a service operation, a service provider *MUST* put the operation's response Protobuf Message into the xref:umessage.adoc[response UMessage]'s `payload` and *MUST* set its `commstatus` attribute to value `OK`.

In case of _erroneous_ execution, a service provider *SHOULD* put a xref:../up-core-api/uprotocol/v1/ustatus.proto[UStatus Message] into the xref:umessage.adoc[response UMessage]'s `payload` and set its `commstatus` attribute to the same value as the UStatus' `code` property.