Liking cljdoc? Tell your friends :D

wagoe.platform.shell.rpc.server

Expose a module's protocol over HTTP, so another process can call it.

The counterpart to …rpc.client: that turns protocol calls into requests, this turns requests back into protocol calls against the local implementation. Together they are what lets a module run as its own service without its callers changing (BOU-90).

FC/IS: shell. The envelope contract is pure and lives in wagoe.platform.core.rpc.

Expose a module's protocol over HTTP, so another process can call it.

The counterpart to `…rpc.client`: that turns protocol calls into requests,
this turns requests back into protocol calls against the local
implementation. Together they are what lets a module run as its own service
without its callers changing (BOU-90).

FC/IS: shell. The envelope contract is pure and lives in
`wagoe.platform.core.rpc`.
raw docstring

default-pathclj

Where rpc-app serves the endpoint. Matches client/default-opts.

Where `rpc-app` serves the endpoint. Matches `client/default-opts`.
sourceraw docstring

handle-envelopeclj

(handle-envelope protocol
                 implementation
                 {:keys [operation args correlation-id] :as envelope})

Invoke one envelope against implementation. Returns a response envelope.

Errors are returned, never thrown: the client reads status and body, and an exception escaping here would surface as a 500 with no operation named — the caller would know something failed but not what it had asked for.

That includes a body that is not an envelope. This endpoint is reachable by anything that can post to it, so :operation may be missing or may not be a name at all; reading it unguarded would throw before the error map that promises to describe the failure could be built.

Invoke one envelope against `implementation`. Returns a response envelope.

Errors are returned, never thrown: the client reads status and body, and an
exception escaping here would surface as a 500 with no operation named — the
caller would know something failed but not what it had asked for.

That includes a body that is not an envelope. This endpoint is reachable by
anything that can post to it, so `:operation` may be missing or may not be a
name at all; reading it unguarded would throw before the error map that
promises to describe the failure could be built.
sourceraw docstring

rpc-appclj

(rpc-app protocol implementation opts)
(rpc-app protocol implementation opts path)

A standalone Ring app serving protocol — for the service's own listener.

Deliberately not a route map for a module's :api or :web slot. Both are rewritten by the router: :api paths gain the version prefix and :web paths gain /web, so a client on the default :path gets a 404 either way. :web is worse than wrong — a POST there is CSRF-validated when CSRF is enabled, so the call would be rejected 403 by a check meant for browser forms, which a service-to-service caller has no token for.

Underneath that: this endpoint invokes port methods, and the public listener is not where it belongs. A sliced-out service should serve it on its own listener, reachable only from inside the deployment — which is what the service launch mode (BOU-91) will start. Until then, mounting is the caller's decision to make explicitly, rather than one this namespace makes look routine.

Format middleware is included, so this handler is complete: it decodes the transit body the client sends and encodes the response.

Args: protocol - the protocol map implementation - a value satisfying it, in this process opts - {:service-key "…"}, or {:auth :none} path - defaults to default-path

Example: (jetty/run-jetty (rpc-app ports/IPaymentProvider provider {:service-key key}) {:port 3001 :join? false})

A standalone Ring app serving `protocol` — for the service's own listener.

Deliberately not a route map for a module's `:api` or `:web` slot. Both are
rewritten by the router: `:api` paths gain the version prefix and `:web`
paths gain `/web`, so a client on the default `:path` gets a 404 either way.
`:web` is worse than wrong — a POST there is CSRF-validated when CSRF is
enabled, so the call would be rejected 403 by a check meant for browser
forms, which a service-to-service caller has no token for.

Underneath that: this endpoint invokes port methods, and the public listener
is not where it belongs. A sliced-out service should serve it on its own
listener, reachable only from inside the deployment — which is what the
service launch mode (BOU-91) will start. Until then, mounting is the
caller's decision to make explicitly, rather than one this namespace makes
look routine.

Format middleware is included, so this handler is complete: it decodes the
transit body the client sends and encodes the response.

Args:
  protocol       - the protocol map
  implementation - a value satisfying it, in this process
  opts           - {:service-key "…"}, or {:auth :none}
  path           - defaults to `default-path`

Example:
  (jetty/run-jetty (rpc-app ports/IPaymentProvider provider
                            {:service-key key})
                   {:port 3001 :join? false})
sourceraw docstring

rpc-handlerclj

(rpc-handler protocol implementation {:keys [service-key auth] :as _opts})

A Ring handler serving protocol backed by implementation.

Use rpc-app unless you have a reason not to — it is this handler with the format middleware it needs, ready for its own listener. Do not merge this into a module's :api or :web routes: the router rewrites both paths, and a POST under /web is CSRF-validated.

Expects the app's format middleware to have decoded the body into :body-params, and leaves encoding the response to it as well — the client asks for application/transit+json, so setting a content type here would override the negotiation and mislabel the body. transit rather than JSON because JSON flattens every keyword to a string, and a protocol returning a keyword status would answer with a string across the hop and nowhere else.

The context an inbound request carries (correlation-id, tenant, auth) is read from the headers and merged onto the envelope, so a downstream call made while handling this one keeps the same correlation-id rather than starting a fresh trace.

Args: protocol - the protocol map, e.g. wagoe.payments.ports/IPaymentProvider implementation - a value satisfying it, in this process opts - {:service-key "…"}, or {:auth :none} to opt out

Callers must present the service key in the x-rpc-service-key header. A missing or wrong one is 401 before anything reaches the implementation — :sigs bounds which operations exist, not who may invoke them. The key is validated at construction, so a service configured without one fails to start instead of coming up unprotected.

Example: (rpc-app payments-ports/IPaymentProvider provider {:service-key key})

A Ring handler serving `protocol` backed by `implementation`.

Use `rpc-app` unless you have a reason not to — it is this handler with the
format middleware it needs, ready for its own listener. Do not merge this
into a module's `:api` or `:web` routes: the router rewrites both paths, and
a POST under `/web` is CSRF-validated.

Expects the app's format middleware to have decoded the body into
`:body-params`, and leaves encoding the response to it as well — the client
asks for `application/transit+json`, so setting a content type here would
override the negotiation and mislabel the body. transit rather than JSON
because JSON flattens every keyword to a string, and a protocol returning a
keyword status would answer with a string across the hop and nowhere else.

The context an inbound request carries (correlation-id, tenant, auth) is
read from the headers and merged onto the envelope, so a downstream call
made while handling this one keeps the same correlation-id rather than
starting a fresh trace.

Args:
  protocol       - the protocol map, e.g. wagoe.payments.ports/IPaymentProvider
  implementation - a value satisfying it, in this process
  opts           - {:service-key "…"}, or {:auth :none} to opt out

Callers must present the service key in the `x-rpc-service-key` header. A
missing or wrong one is 401 before anything reaches the implementation —
`:sigs` bounds which operations exist, not who may invoke them. The key is
validated at construction, so a service configured without one fails to
start instead of coming up unprotected.

Example:
  (rpc-app payments-ports/IPaymentProvider provider {:service-key key})
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close