# gRPC requests

Source: https://apigenie.pl/docs/reference/cli/test/grpc
Part of the reference of [test](https://apigenie.pl/docs/reference/cli/test.md).
Its other pages: [Request files](https://apigenie.pl/docs/reference/cli/test/requests.md), [Variables and OAuth 2](https://apigenie.pl/docs/reference/cli/test/variables.md), [Assertions and scripts](https://apigenie.pl/docs/reference/cli/test/assertions.md), [Validation](https://apigenie.pl/docs/reference/cli/test/validation.md), [Generated requests](https://apigenie.pl/docs/reference/cli/test/generate.md), [GraphQL requests](https://apigenie.pl/docs/reference/cli/test/graphql.md), [WebSocket and MQTT requests](https://apigenie.pl/docs/reference/cli/test/websocket-mqtt.md), [Kafka requests](https://apigenie.pl/docs/reference/cli/test/kafka.md), [AMQP requests](https://apigenie.pl/docs/reference/cli/test/amqp.md), [Importing collections](https://apigenie.pl/docs/reference/cli/test/import.md), [httpYac compatibility](https://apigenie.pl/docs/reference/cli/test/httpyac.md).

`GRPC` requests call the methods of the services of the `.proto` file given as `--spec`: the request
line names the method, the headers are the call's metadata, the body is the message as JSON, and the
assertions check the status, the response metadata and the response message. A request is written
as httpYac writes it:

```http
@host = localhost:50051

### say hello
GRPC {{host}}/acme.greeter.v1.Greeter/SayHello
x-tenant: acme

{"name": "Ann"}

?? status == 0
?? body message == Hello Ann
?? header grpc-status == 0
```

```sh
apigenie test --spec greeter.proto greeter.http
```

```text
PASS GRPC localhost:50051/acme.greeter.v1.Greeter/SayHello -> OK (6 ms) acme.greeter.v1.Greeter/SayHello
Requests: 1 passed, 0 failed, 0 skipped
Contract: 1 calls (0 undocumented), 0 errors, 0 warnings
Coverage: 33.3% of 3 methods
  not tested: acme.greeter.v1.Greeter/SayHelloToAll, acme.greeter.v1.Greeter/Ping
```

- **The request line** is `GRPC HOST:PORT/package.Service/Method`, or a URL with `grpc://`, or with
  `grpcs://` for TLS. The method must be one of the file's: another is a failed request.
- **Headers** are the call's metadata (names in lower case); `-bin` values are sent as written,
  base64-encoded.
- **The body** is the request message in its proto3 JSON form (field names or their JSON names,
  64-bit integers as numbers or strings, enum names, base64 bytes, the well-known types in their
  own forms); no body is `{}`. A body that isn't a valid message fails the request before anything
  is sent, naming the field: `the body isn't a valid acme.greeter.v1.HelloRequest: name: expected a string`.
- **The `.proto` file is `--spec`**, with its imports looked up in `--proto-path` directories, then
  next to the file, then among the standard files (`google/protobuf/*`, `google/api/*`,
  `google/rpc/*`), as `apigenie-server --proto-path` does. httpYac's `proto < ./file.proto` line is
  read and ignored with a warning.
- **Assertions and scripts** see the call as a response: `status` is the gRPC status code (`0` for
  OK, `5` for NOT_FOUND) and the status text its name, the headers are the response metadata and
  the trailers (`grpc-status`, `grpc-message` among them), and the body is the response message as
  JSON. A server-streaming or bidi-streaming call's body is a JSON array of its messages.
- **Every kind of method.** Client- and bidi-streaming methods take a stream of messages, written
  as for [WS regions](/docs/reference/cli/test/websocket-mqtt): lines `===` separate them, and
  `=== wait-for-server` waits for a message of the server before the next one is sent (bidi
  methods only). After the last message the call is half-closed, and its end (the trailers) is
  awaited for `# @timeout` (`--message-timeout`, 5000 ms); a call that doesn't end in time is
  cancelled and fails. Unary and server-streaming methods take one message: more fail the request.
- **HTTP/2**, cleartext with prior knowledge (h2c), or over TLS with ALPN `h2` for `grpcs://` (and
  `https://`) URLs, verified as `https://` requests are (`--ca-cert`, `--insecure`). `--timeout`
  bounds the connection and each wait for the server, and is sent as `grpc-timeout`.

```http
### a client stream: the messages, then one answer
GRPC {{host}}/acme.chat.v1.Chat/Upload

{"author": "Ann", "text": "hi"}
===
{"author": "Bob", "text": "hello"}

?? body lines == 2

### a bidi stream that waits for each answer before it goes on
GRPC {{host}}/acme.chat.v1.Chat/Talk

{"author": "Ann", "text": "hi"}
=== wait-for-server
{"author": "Ann", "text": "bye"}

?? body $.length == 2
?? body $[1].text == re: bye
```

Each call is checked with the checks of
[gRPC contract testing](/docs/reference/server/grpc#contract-testing-of-a-grpc-api): the
request and response messages against their types (fields marked
`[(google.api.field_behavior) = REQUIRED]` included), each message of a stream at `message[0]`,
`message[1]`, ..., the status and its `google.rpc` details, the number of messages of a unary or
client-streaming call. The coverage counts the file's methods. Without a `.proto` file
as `--spec`, `GRPC` requests are skipped; HTTP requests in the same files are sent but not checked.
