Skip to content

Commit

Permalink
Update PROTOCOL.md
Browse files Browse the repository at this point in the history
Addressing review comments.
  • Loading branch information
mocax authored Jan 30, 2018
1 parent 77e721b commit c9c3d98
Showing 1 changed file with 38 additions and 57 deletions.
95 changes: 38 additions & 57 deletions PROTOCOL.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
# Twirp Wire Protocol

This document defines the Twirp wire protocol over HTTP.

## Conventions

The requirement level keywords "MUST", "MUST NOT", "REQUIRED",
"SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
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
syntax](https://tools.ietf.org/html/rfc5234).
This document defines the Twirp wire protocol over HTTP. The
current protocol version is v5.

## Overview

Expand All @@ -28,70 +19,54 @@ the client can communicate with the server by making RPC calls.

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
library being used.

### URLs

**URL ::= Base-URL "/" [ Package "." ] Interface "/" Method**
In [ABNF syntax](https://tools.ietf.org/html/rfc5234), Twirp's URLs
have the following format:

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

The Twirp wire protocol uses HTTP URLs to directly specify the RPC
endpoints on the server for sending the requests. such direct mapping
The Twirp wire protocol uses HTTP URLs to specify the RPC
endpoints on the server for sending the requests. Such direct mapping
makes the request routing simple and efficient. The Twirp URLs have
the following components.

* **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".
typically published via API documentation or service discovery.
Currently, it should only contain URL `scheme` and `authority`. For
example, "https://example.com".

* **Package** is the proto `package` name for an API, which is often
considered as an API version. For example,
`example.calendar.v1`. This component is omitted if the API
definition doesn't have a package name.

* **Interface** is the proto `service` name for an API. For example,
* **Service** is the proto `service` name for an API. For example,
`CalendarService`.

* **Method** is the proto `rpc` name for an API method. For example,
`CreateEvent`.

### Requests

**Request ::= Request-Headers Request-Body**

Twirp always uses HTTP POST method to send requests, because it
closely matches the semantics of RPC methods.

The **Request-Headers** are normal HTTP headers. The Twirp wire
protocol uses the following headers.

* **Authorization** header is often used to pass user credentials
from the client to the server, such as OAuth access token or
JWT token.

* **Content-Type** header indicates the proto message encoding, which
should be one of "application/x-protobuf", "application/json". The
should be one of "application/protobuf", "application/json". The
server uses this value to decide how to parse the request body,
and encode the response body.

* **User-Agent** header indicates the client application and its
runtime environment. While the server should not use this
information for request processing, this header is heavily used
for analytics and troubleshooting purposes.

* **RPC-Timeout** header indicates the client-specified request
timeout in seconds, such as "10". If **RPC-Timeout** is omitted, the
server should use a pre-configured timeout value, by default it
should be 10 seconds.

The **Request-Body** is the encoded request message, contained in the
HTTP request body. The encoding is specified by the `Content-Type`
header.

### Responses

**Response ::= Response-Headers Response-Body**

The **Response-Headers** are just normal HTTP response headers. The
Twirp wire protocol uses the following headers.

Expand All @@ -111,6 +86,8 @@ corresponding wire payloads.
The example assumes the server base URL is "https://example.com".

```proto
syntax = "proto3";
package twirp;
service Echo {
Expand All @@ -131,7 +108,7 @@ message HelloResponse {
```
POST /twirp.Echo/Hello HTTP/1.1
Host: example.com
Content-Type: application/x-protobuf
Content-Type: application/protobuf
Content-Length: 15
<encoded HelloRequest>
Expand All @@ -152,7 +129,7 @@ Content-Length: 27

```
HTTP/1.1 200 OK
Content-Type: application/x-protobuf
Content-Type: application/protobuf
Content-Length: 15
<encoded HelloResponse>
Expand All @@ -170,24 +147,28 @@ Content-Length: 27

## Errors

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)
on how to map typical server errors to HTTP status codes.
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
the errors are human-readable in any setting.

### Timeout errors
Twirp errors are a JSON object with three keys:

For a single request, there is a client-specified timeout and a
server-configured timeout. If a request misses the server-configured
timeout, the server must return a `503` error. If a request misses
the client-specified timeout that it is shorter then the server-
configured timeout, the server must return a `504` error.
This allows more accurate measurement of the server availability.
* **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.

### Network errors
Example:
```
{
"code": "permission_denied",
"msg": "thou shall not pass",
"meta": {
"target": "Balrog"
}
}
```

If a client fails to reach the server due to network errors, the
client library must report HTTP status code `502` to the client
application. This helps users distinguishing network errors from
server errors.
For more information, see https://github.com/twitchtv/twirp/wiki/Errors.

0 comments on commit c9c3d98

Please sign in to comment.