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

Create PROTOCOL.md #71

Merged
merged 6 commits into from
Feb 2, 2018
Merged

Create PROTOCOL.md #71

merged 6 commits into from
Feb 2, 2018

Conversation

mocax
Copy link
Contributor

@mocax mocax commented Jan 30, 2018

Draft the wire protocol spec for Twirp based on latest discussions. It reflects the existing Twirp wire spec, plus best practice from proto3, gRPC, HTTP, and JSON. The spec should be usable for developers to build clients and servers using Twirp wire protocol without much dependency.

Issue #, if available:
#71
Description of changes:
Write up the Twirp wire protocol.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Draft the wire protocol spec for Twirp based on latest discussions. It reflects the existing Twirp wire spec, plus best practice from proto3, gRPC, HTTP, and JSON. The spec should be usable for developers to build clients and servers using Twirp wire protocol without much dependency.
@daroot
Copy link

daroot commented Jan 30, 2018

application/x-protobuf or application/protobuf? The code uses the latter, not the former.

@slaskis
Copy link

slaskis commented Jan 30, 2018

Charles Proxy seems to support either application/x-protobuf or application/x-google-protobuf and it's nice to have supported tooling. Although maybe using application/protobuf in Twirp might coax the Charles devs to add that Content-Type too...

@mocax
Copy link
Contributor Author

mocax commented Jan 30, 2018

Google didn't complete its IETF application, https://tools.ietf.org/html/draft-rfernando-protocol-buffers-00. So technically it still is application/x-protobuf, and it is widely used.

Copy link
Contributor

@spenczar spenczar left a comment

Choose a reason for hiding this comment

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

Thanks for kicking this off!

I think we should be describing the current version of Twirp with this document. We can make an additional document for v6 which can signal which things are done-and-decided for the upcoming version.

PROTOCOL.md Outdated

The Twirp wire protocol supports both binary and JSON encodings of
proto messages, and works with any HTTP client and any HTTP version.
However, certain capabilities may be limited by the actual HTTP
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think it's worth including this caveat until we can actually say this precisely.

PROTOCOL.md Outdated

### URLs

**URL ::= Base-URL "/" [ Package "." ] Interface "/" Method**
Copy link
Contributor

Choose a reason for hiding this comment

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

Please change Interface to Service.

Also, the current routing is URL ::= Base-URL "/twirp/" [ Package "." ] Service "/" Method, please update this to match the /twirp prefix.

PROTOCOL.md Outdated

**URL ::= Base-URL "/" [ Package "." ] Interface "/" Method**

The Twirp wire protocol uses HTTP URLs to directly specify the RPC
Copy link
Contributor

Choose a reason for hiding this comment

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

remove "directly"

PROTOCOL.md Outdated
**URL ::= Base-URL "/" [ Package "." ] Interface "/" Method**

The Twirp wire protocol uses HTTP URLs to directly specify the RPC
endpoints on the server for sending the requests. such direct mapping
Copy link
Contributor

Choose a reason for hiding this comment

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

Capitalize "direct"

PROTOCOL.md Outdated

* **Base-URL** is the virtual location of a Twirp API server, which is
typically published via API documentation or service discovery. For
example, "https://example.com/apis".
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a bad example right now, as the base URL in v5 cannot safely include a path component.

I think we should be more specific here. The Base URL should contain only the "scheme" and "authority" (commonly known as "host and port") portions of a RFC 3986 URI.

We will likely change this to allow a path component in v6, as discussed in #55.

PROTOCOL.md Outdated

### Network errors

If a client fails to reach the server due to network errors, the
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we should specify this. I don't think client libraries should be exposing HTTP status codes, just Twirp error codes.

PROTOCOL.md Outdated
If an error occurs when the server processes a request, the server
must return an error payload as the response message, and correctly
set the HTTP status code. Please see
[`google.rpc.Code`](https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto)
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't strictly follow google.rpc.Code. We use our own error codes, heavily based on those but with some modifications: the codes are a string on the wire for human readability, and we add the bad_route error code. See https://github.com/twitchtv/twirp/blob/master/errors.go#L138-L275.

PROTOCOL.md Outdated
## Errors

If an error occurs when the server processes a request, the server
must return an error payload as the response message, and correctly
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 we should describe Twirp's error payload in detail here.

Twirp error responses are always JSON-encoded (regardless of the request's Content-Type), with a corresponding Content-Type: application/json header. This ensures that they are human-readable in any setting.

They are a JSON object with three keys:

  • code: One of the Twirp error codes as a string.
  • msg: A human-readable message describing the error as a string.
  • meta: An object with string keys and values holding arbitrary additional metadata describing the error.

For example:

{
    "code": "permission_denied",
    "msg": "thou shall not pass",
    "meta": {
        "target": "Balrog"
    }
}

See https://github.com/twitchtv/twirp/wiki/Errors.

PROTOCOL.md Outdated

## Conventions

The requirement level keywords "MUST", "MUST NOT", "REQUIRED",
Copy link
Contributor

Choose a reason for hiding this comment

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

None of these keywords are used in this document. Let's drop this paragraph.

PROTOCOL.md Outdated
and "OPTIONAL" used in this document are to be interpreted as
described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt).

The grammar rules used in this document are using [ABNF
Copy link
Contributor

Choose a reason for hiding this comment

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

We only use ABNF in one place where it's useful, which is in describing the URL. Let's delete this paragraph and just say something like In [ABNF syntax](https://tools.ietf.org/html/rfc5234), Twirp's URLs follow this format: ...

Then, we can get rid of this Conventions section altogether, which is good.

Addressing review comments.
@mocax
Copy link
Contributor Author

mocax commented Jan 30, 2018

Should be all fixed.

Copy link
Contributor

@spenczar spenczar left a comment

Choose a reason for hiding this comment

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

Very close!

PROTOCOL.md Outdated
**Proto Request**

```
POST /twirp.Echo/Hello HTTP/1.1
Copy link
Contributor

Choose a reason for hiding this comment

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

The URL here should be /twirp/twirp.Echo/Hello. Same for JSON.

The stuttering of 'twirp' here is not ideal. Could you change the package to something like package example.echoer?

Change proto package name to example.echoer.
@mocax
Copy link
Contributor Author

mocax commented Feb 2, 2018

Done.

Use google/protobuf.
Copy link
Contributor

@spenczar spenczar left a comment

Choose a reason for hiding this comment

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

Thank you for writing this!

@spenczar spenczar merged commit 3c47b82 into twitchtv:master Feb 2, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants