Repository navigation
Conversation
|
See more at https://github.com/apify/apify-client-js/actions/runs/41030185240#summary-123977815884 |
|
|
||
| The request carries the client's API token in the `Authorization` header. The platform removes the token before it forwards the request, so the token doesn't reach the Actor's code. | ||
|
|
||
| If the Actor reads the `Authorization` header for its own authentication, pass that header in `headers`, and send your Apify token in the `X-Apify-Authorization` header instead. A header you pass in `headers` replaces the client's `Authorization` header for that request. |
There was a problem hiding this comment.
Why don't we do this by default (send the token as X-Apify-Authorization with every standby request)?
Imo we shouldn't limit the set of allowed user-based headers only because some names are used internally.
There was a problem hiding this comment.
ok, so:
- we always use X-Apify-Authorization, platforms authenticates with it, and strips it (it doesnt reach the Actor's code)
- Authorization header is free for the Actor's own auth and is passed through unchanged
|
|
||
| ## Timeouts, retries, and errors | ||
|
|
||
| When no server run is ready, the first request waits for the platform to start one, which can take a few minutes. The method uses the `long` timeout tier by default for that reason. You can pass a different `timeoutSecs`, or a `signal` to abort the request, the same way as for API calls. For details, see [Timeouts](./10_timeouts.mdx). |
There was a problem hiding this comment.
first request waits for the platform to start one, which can take a few minutes
...few minutes? I guess we should have kept the "stand-by" naming 😅
There was a problem hiding this comment.
👀 ... dropping all the time-scoped information 😄
|
|
||
| When no server run is ready, the first request waits for the platform to start one, which can take a few minutes. The method uses the `long` timeout tier by default for that reason. You can pass a different `timeoutSecs`, or a `signal` to abort the request, the same way as for API calls. For details, see [Timeouts](./10_timeouts.mdx). | ||
|
|
||
| An error status from the Actor's server throws an `ApifyApiError`, like an error from the API. Server errors and rate-limit responses are retried with the client's retry settings, so a request that the server failed to answer may reach it more than once. If your endpoint isn't safe to call twice, lower `maxRetries` on the client. For details, see [Retries](./04_retries.mdx) and [Error handling](./03_error_handling.mdx). |
There was a problem hiding this comment.
I'm not sure I'm sold on this... we don't know anything about the requests / responses of the Actor Server. If it's the standby controller speaking (e.g., rate-limiting the request before it reaches the Actor itself), there it might make sense.
But in case of the Actor Server returning a non-2xx response, I'd rather just return that from the .request() call, not touching it at all.
There was a problem hiding this comment.
Agreed, updated - we now just return the response as is (and only retry 429 and 503)
| {ServerExample} | ||
| </CodeBlock> | ||
|
|
||
| The method resolves to the server's response, with the body parsed by its content type in `data`. To find out which endpoints an Actor serves, see its page in [Apify Store](https://apify.com/store), its README, or its OpenAPI specification. For details, see [Server URL and OpenAPI specification](#server-url-and-openapi-specification). |
There was a problem hiding this comment.
with the body parsed by its content type in
data.
idk how to feel about this. I suppose this means that Content-Type: application/json gets parsed into a JS object?
Is there a way to opt-out of this? Or, e.g., stream the response, or get it as raw bytes etc etc.?
There was a problem hiding this comment.
We could add an option to specify a response type. Check it out now.
… to HttpClient.call()
Adds
ActorClient.server(), which returns anActorServerClientfor Server Actors (formerly Actor Standby):request()sends a request to the Actor's server. The host always comes from the Actor'sstandbyUrl. The token goes in theX-Apify-Authorizationheader, which the platform strips, so headers the caller passes,Authorizationincluded, reach the Actor as they are.request()returns the server's response whatever its status. Only 429 and 503 are retried, since other statuses may come from the Actor's code. Network errors and timeouts aren't retried, since the Actor may have already handled the request. It throws only when it gets no response: the Actor doesn't exist or isn't a Server Actor, or the request fails or times out.request()sends bodies uncompressed unlesscompressionis set, returns the body parsed, as a buffer, or as a stream depending onresponseType, and defaults to thelongtimeout to cover a cold start.getUrl()returns the server URL. It's fetched once perActorClient, bygetUrl()orgetOpenApiSpec().getOpenApiSpec()returns the web server schema from the build that serves the server (actorStandby.build, orlatest), orundefinedif there's none.ActorClient.standby()is a deprecated alias ofserver()and will be removed in v4.Other changes:
ApifyRequestConfigtakes new per-request options:compression,authorizationHeader,throwOnErrorStatus,retryStatusCodes, andretryTransportErrors. A custom HTTP client that overridescall()should honor them.AxiosHttpClientdrops theX-Apify-Authorizationheader on a redirect to another origin, so an Actor can't redirect the token to another host.Port of apify/apify-client-python#1153.
Closes: #1159
✍️ Drafted by Claude Code