# Introduction

This example demonstrates the use of Protocol Buffers to define and implement a networked API. The Kiosk API allows users to manage a collection of displays that are able to display digital signs containing text and images. The Kiosk API includes a streaming method that allows displays to immediately update in response to configuration changes on the API server. The Kiosk API is implemented using gRPC, which includes support for streaming APIs. All non-streaming API methods can also be provided as REST services using standard gRPC to JSON transcoding.

The original gRPC-based API definition is in the [googleapis/kiosk](https://github.com/googleapis/kiosk/) repository.

We have taken the `gRPC` representation of this service and converted it into `TypeSpec` to understand what gaps might be in the language. Note we're not trying to create an `TypeSpec` which could create the equivalent `protobuf` as an output format, but are focusing on the swagger created from both `gRPC` and `TypeSpec` and trying to understand the differences.

## Files

- [kiosk.proto](kiosk.proto) - The original [kiosk.proto](https://github.com/googleapis/kiosk/blob/master/protos/kiosk.proto).
- [kiosk.swagger.json](kiosk.swagger.json) - Swagger generated from the `kiosk.proto` file using `protoc-gen-openapiv2`.
- [kiosk.tsp](kiosk.tsp) - A hand-written TypeSpec file which tries to stay as close as possible to a RPC based request/response model.
- [types.tsp](types.tsp) - Some generic types which could move into a standard type library.
- [openapi.json](openapi.json) - Swagger generated by `tsp compile` from `kiosk.tsp`.

## Open questions and comments

### `rpc CreateKiosk(Kiosk)` is broken in OpenAPI

The gRPC definition of `CreateKiosk`:

```protobuf
// Create a kiosk. This enrolls the kiosk for sign display.
rpc CreateKiosk(Kiosk) returns (Kiosk) {
    option (google.api.http) = { post: "/v1/kiosks" };
}
```

doesn't translate at all to OpenAPI and the Swagger produced has no request body:

```json
"post": {
   "summary": "Create a kiosk. This enrolls the kiosk for sign display.",
   "operationId": "Display_CreateKiosk",
   "responses": {
       "200": {
       "description": "A successful response.",
       "schema": {
           "$ref": "#/definitions/kioskKiosk"
       }
       },
       "default": {
       "description": "An unexpected error response.",
       "schema": {
           "$ref": "#/definitions/rpcStatus"
       }
       }
   },
   "tags": [
       "Display"
   ]
   }
}
```

TypeSpec has an advantage as it won't even allow the corresponding `op` to compile and it will throw an error that there isn't a unique body specified. Alteratively, the `library` service does it better and in a way that translates cleanly to TypeSpec:

```protobuf
// Request message for LibraryService.CreateBook.
message CreateBookRequest {
    // The name of the shelf in which the book is created.
    string name = 1 [
        (google.api.field_behavior) = REQUIRED,
        (google.api.resource_reference).type = "Shelf"
    ];

    // The book to create.
    Book book = 2 [(google.api.field_behavior) = REQUIRED];
}

// Creates a book, and returns the new Book.
rpc CreateBook(CreateBookRequest) returns (Book) {
    option (google.api.http) = {
      post: "/v1/{name=shelves/*}/books"
      body: "book"
    };
    option (google.api.method_signature) = "name,book";
}
```

### Using `...` in Request parameters

In this example and the Library example we see a few different patterns on how a gRPC `rpc` definition uses different `message`. While some directly use things that look like TypeSpec models as request and response messages, a more general patter is that a gRPC op `Foo` usually has `FooRequest` and `FooResponse` messages which embed models inside, e.g.

a natural direct mapping of:

```protobuf
message GetKioskRequest {
  // Required.
  int32 id = 1;
}

// Get a kiosk.
rpc GetKiosk(GetKioskRequest) returns (Kiosk) {
    option (google.api.http) = { get: "/v1/kiosks/{id}" };
}
```

would be

```
model GetKioskRequest {
    @path
    id: int32;
}

@doc("Get a kiosk.")
@get
@route("kiosks/{id}")
op GetKiosk(... GetKioskRequest): Kiosk | RpcStatus;
```

This produces slightly different, but functionality equivalent swagger in that the gRPC generator inline the parameter id, while TypeSpec create a `"$ref": "#/parameters/GetKioskRequest"` which points to a single parameter, `id`.

If we wrote the TypeSpec directly with the id specified in the `op` parameters we get equivalent to the gRPC version:

```
@doc("Get a kiosk.")
@get
@route("kiosks/{id}")
op GetKiosk(@path id: int32): Kiosk | RpcStatus;
```

the downside with this approach is that it's not as convenient to add documentation inside the parameter. Could we perhaps add a new decorator @parameter_doc("id","This is a unique identified") that we add to the `op` ?
