owncloud / ocis-hello

:atom_symbol: Example extension for oCIS
https://owncloud.dev/extensions/ocis_hello/
Apache License 2.0
10 stars 13 forks source link

[WIP | Spec] Protobuf File #67

Open refs opened 4 years ago

refs commented 4 years ago

While designing a Protobuf API taking into consideration Javascript consumers we need to mind that the generated js client will make use of define endpoints on the protobuf file. As a way of easing development and not having the overhead of writing new Encoder / Decoders and leveraging the use of reflection, requests that make use of the JS generated client MUST be defined as POST.

This is due to RPC and REST are different API design, and as we're designing for RPC and not Restful endpoints, our generated swagger client needs to be aware of this design choice and not get into the nitty-gritty of understanding REST routes, but only Marshal / Unmarshal JSON on the request body.

This design choice was made taking into consideration the HTTP Spec, which recommends GET requests not to contain a body and Swagger enforces this:

GET, DELETE and HEAD are no longer allowed to have request body because it does not have defined semantics as per RFC 7231.

This causes our generation to panic on GET requests.

Root causes: JS clients does not currently support gRPC (at the moment of this writing).

kulmann commented 4 years ago

The paths for the generated http post endpoints have the primary requirement to be unique, secondary requirement to be developer friendly. They do not have the requirement to adhere RESTful design.

We decided to go with paths like shown in the following example. The generated http endpoints will never be visible for developers, as they are internally used in the generated JavaScript client. For debugging purposes it might still be useful to have human readable paths.

service ValueService {
  rpc SaveSettingsValue(SaveSettingsValueRequest) returns (SaveSettingsValueResponse) {
    option (google.api.http) = {
      post: "/api/v0/settings/value-save",
      body: "*"
    };
  };
  rpc GetSettingsValue(GetSettingsValueRequest) returns (GetSettingsValueResponse) {
    option (google.api.http) = {
      post: "/api/v0/settings/value-get",
      body: "*"
    };
  };
  rpc ListSettingsValues(ListSettingsValuesRequest) returns (ListSettingsValuesResponse) {
    option (google.api.http) = {
      post: "/api/v0/settings/values-list",
      body: "*"
    };
  };
}
kulmann commented 4 years ago

One drawback of this is, that the returned status codes have to be handled and will probably not be what a developer would expect. E.g. a successful get request in the above style would not return http 200, but http 201.

pascalwengerter commented 3 years ago

@refs what's the state of things here currently? The repo has experienced quite some changes I assume