# How provider calls are made

This is the detail behind [Calling](calling.md): which keys an operation
takes, how its input is sent, who may call it, whether it may be sent
again, and how its answer is classified and read.

- **An operation's keys.** `method:` and `path:` are required; `input:`
  is one of the package's object types, and without it the call takes
  nothing; without `output:` it gives nothing and its answer isn't read.
  `changes:` defaults to `true` for every method but `GET`, as the
  importer writes it, and `idempotent:` to `false`. `source:`, `docs:`,
  `scope:` and the flag `large_output:` are read where they are used;
  `wire_output:` and `decode:` are under "Wire encodings, decoders and
  retries". Anything else, a malformed path, a placeholder no input field is
  sent as, or a failure that isn't the package's, is
  `package.operation_invalid`.
- **How the input is sent.** Written as the package's JSON, its members
  by their spellings on the wire; each placeholder in `path:` takes the
  member of its spelling, as text, escaped, as one segment (a value that
  would leave it, empty, `.` or `..`, is a fault, and nothing is sent);
  the rest is a `GET`'s or
  `DELETE`'s query (a list as the key repeated, `none` left out, an
  object as its JSON) and every other method's JSON body.
- **Who calls.** Only an action, of a domain the connection's `domains:`
  lists (`connection.domain_not_listed` otherwise); never a function, and
  never a test, which reaches a provider through an action with the
  provider faked. A `basic` credential is the setting's `user:password`.
- **Its failures are conditions of the call.** An operation that lists
  failures needs `attempt` or `match`. `attempt`'s arms are keyed by the
  failures' codes and name the app's failure of the same kind
  (`failure.mapping_kind`); the provider's failure becomes the app
  failure's internal cause. A code no arm maps, or one the operation
  doesn't declare, is a fault naming the operation and the code, its
  classification `internal_fault`, so a package failure never reaches an
  app's `fails` list. A `match` on the call names the package's failures,
  as a library function's.
- **Whether it may be sent again.** An operation that changes nothing is
  safe; one marked `idempotent: true` is keyed when its package has
  `idempotency:`, and safe without one (repeating it changes nothing);
  any other change is unkeyed, so one whose outcome is unknown is parked
  rather than sent again.
- **The key**, as
  [Several changing calls in one action](several-changing-provider-calls.md)
  uses it, is `jd1_` and 32 characters of RFC 4648
  base32 in lower case, the first 160 bits of a SHA-256 over the parts,
  each given by its length so two sets of parts never run together, and
  cut to `max_length:`. The application is its name (its folder's until
  `app.jadpo` names it); the environment the host its environment setting
  chose, `live` or `sandbox`, or the address a `host:` setting gives. In
  a route, the caller's idempotency scope and the client's
  `Idempotency-Key`, whether or not a store keeps it, or `request` and the
  request's id; in a subscriber, `delivery` and the delivery's id, but a
  sign-in email's attempt a key of its own
  ([Built-in emails](built-in-emails.md));
  anywhere else (a schedule, a test's call) a key made from the
  invocation's randomness the first time a call needs one. The step
  counts the invocation's keyed calls from 1, a delivery's attempt from 1
  wherever it runs, and an action run again after a concurrent change
  takes the same steps; the generation is 0 until a provider's
  `new_key_on:`.
- **Where it is sent.** HTTPS, or plain HTTP only to this machine
  (`localhost`, an IPv4 address in `127.0.0.0/8`, `[::1]`, the host read
  as an address, so `127.api.example.com` is elsewhere), which is how a test reaches its
  server; any other address, or a connection whose address or credential
  has no value, is `misconfigured` and logged as refused, sent to nobody.
  The call waits `timeout:` (3 seconds by default), a duration
  written out (`connection.value_invalid` otherwise). It sends `Accept`
  and `Content-Type: application/json`, `User-Agent: jadpo`, the
  credential as `Authorization`, and the key in the package's header.
- **The package driver** is one driver for every package connection,
  over the fetch its host gives. Natively that is an HTTP/1.1 client on
  the worker's thread, with its connections kept per host, checking the
  certificate and the host against Mozilla's roots for HTTPS. It
  classifies what came back: a `2xx` as sent, unless
  `failed_when:` marks it, then the code at `error_code:`; a redirect
  `misconfigured`, and a `401` or `403` as the credential's source says:
  `misconfigured` for a setting's, the connection's for every call; `408`, `429` or the package's `in_use:`
  code `unavailable`; any other `4xx` the code at `error_code:`, a fault
  when there is none; a `5xx`, no answer in time, a connection broken
  once the request had left, or an answer over 10 MB as an answer that
  may have acted, which is `unavailable` for a keyed or safe call and
  `outcome_unknown` for an unkeyed one; a request that never left
  `unavailable`. `reused:` is a code like any other, so a key sent with a
  different request is a fault.
- **The answer** is kept as sent on a recording, and decoded again by the
  build that replays it. It is read from `output_at:` (nothing there is a
  fault) with its output type's codec, every field it declares decoded as
  it arrives; members the package's types don't declare are left out, so
  a provider adding fields breaks nothing. Only the fields code reads
  are decoded ("Wire encodings, decoders and retries"), so a changed
  field nobody reads breaks nothing either. A value that doesn't decode is a fault
  naming the operation, the field and the rule, never the value.
- **`wire_name:`** goes in a field's block and in an enum variant's block;
  a variant whose block holds only `wire_name:` carries no data, and one
  with data is tagged with its spelling. It is the spelling wherever the
  type's JSON is written or read: a provider's request and answer,
  `json.read` and `json.write`, an event's payload. Only a provider
  package's types give one, never empty, never the name itself, and never
  two members of one type under one spelling (`package.wire_name_invalid`).
- **A package's object types are built through its name**,
  `AcmeCouriers.CreateBooking { ... }`, as its other types are written.

> Not built yet: a connection's protocol other than `Protocol.json_http`
> and `.aws_json`, and a credential scheme other than
> `CredentialScheme.bearer`, `.basic`, `.header` (which
> [AI](ai.md) packages use) and `.aws_sigv4`, is
> `toolchain.not_built_yet` at the call. A host holding a setting's
> placeholder (`{project_ref}`) isn't filled yet.
