|
| 1 | +# Get Requests and Caching |
| 2 | + |
| 3 | +Connect supports performing idempotent, side-effect free requests using an HTTP GET-based protocol. |
| 4 | +This makes it easier to cache certain kinds of requests in the browser, on your CDN, or in proxies and |
| 5 | +other middleboxes. |
| 6 | + |
| 7 | +If you are using clients to make query-style requests, you may want the ability to use Connect HTTP GET |
| 8 | +request support. To opt-in for a given procedure, you must mark it as being side-effect free using the |
| 9 | +`MethodOptions.IdempotencyLevel` option: |
| 10 | + |
| 11 | +```protobuf |
| 12 | +service ElizaService { |
| 13 | + rpc Say(SayRequest) returns (SayResponse) { |
| 14 | + option idempotency_level = NO_SIDE_EFFECTS; |
| 15 | + } |
| 16 | +} |
| 17 | +``` |
| 18 | + |
| 19 | +Services will automatically support GET requests using this option. |
| 20 | + |
| 21 | +It is still necessary to opt-in to HTTP GET on your client, as well. Generated clients include a |
| 22 | +`use_get` parameter for methods that are marked with `NO_SIDE_EFFECTS`. |
| 23 | + |
| 24 | +=== "Async" |
| 25 | + |
| 26 | + ```python |
| 27 | + response = await client.say(SayRequest(sentence="Hello"), use_get=True) |
| 28 | + ``` |
| 29 | + |
| 30 | +=== "Sync" |
| 31 | + |
| 32 | + ```python |
| 33 | + response = client.say(SayRequest(sentence="Hello"), use_get=True) |
| 34 | + ``` |
| 35 | + |
| 36 | +For other clients, see their respective documentation pages: |
| 37 | + |
| 38 | +- [Connect Node](https://connectrpc.com/docs/node/get-requests-and-caching) |
| 39 | +- [Connect Web](https://connectrpc.com/docs/web/get-requests-and-caching) |
| 40 | +- [Connect Kotlin](https://connectrpc.com/docs/kotlin/get-requests-and-caching) |
| 41 | + |
| 42 | +## Caching |
| 43 | + |
| 44 | +Using GET requests will not necessarily automatically make browsers or proxies cache your RPCs. |
| 45 | +To ensure that requests are allowed to be cached, a handler should also set the appropriate headers. |
| 46 | + |
| 47 | +For example, you may wish to set the `Cache-Control` header with a `max-age` directive: |
| 48 | + |
| 49 | +```python |
| 50 | +ctx.response_headers()["cache-control"] = "max-age=604800" |
| 51 | +return SayResponse() |
| 52 | +``` |
| 53 | + |
| 54 | +This would instruct agents and proxies that the request may be cached for up to 7 days, after which |
| 55 | +it must be re-requested. There are other [`Cache-Control` Response Directives](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#response_directives) |
| 56 | +that may be useful for your application as well; for example, the `private` directive would specify that |
| 57 | +the request should only be cached in private caches, such as the user agent itself, and _not_ CDNs or reverse |
| 58 | +proxies — this would be appropriate, for example, for authenticated requests. |
| 59 | + |
| 60 | +## Distinguishing GET Requests |
| 61 | + |
| 62 | +In some cases, you might want to introduce behavior that only occurs when handling HTTP GET requests. |
| 63 | +This can be accomplished with `RequestContext.http_method`: |
| 64 | + |
| 65 | +```python |
| 66 | +if ctx.http_method() == "GET": |
| 67 | + ctx.response_headers()["cache-control"] = "max-age=604800" |
| 68 | +return SayResponse() |
| 69 | +``` |
0 commit comments