com.walmartlabs.lacinia.resolve

Complex results for field resolver functions.

Resolver functions may return a value directly, or return a value in an immediate or asynchronous ResolverResult. The resolved value may be wrapped in a a modifier:

The modifiers exist to resolve a value and to perform a side effect, such as adding an error to the execution result.

A value or wrapped value may be returned asynchronously using a ResolverResultPromise.

The FieldResolver protocol allows a Clojure record to act as a field resolver function.

*callback-executor*

dynamic

added in 0.20.0

If non-nil, then specifies a java.util.concurrent.Executor (typically, a thread pool of some form) used to invoke callbacks when ResolveResultPromises are delivered.

Starting in 1.2, this is always bound when query execution begins.

as-resolver-fn

added in 0.24.0

(as-resolver-fn field-resolver)

Wraps a FieldResolver instance as a field resolver function.

If the field-resolver provided is a function or a Var, it is returned unchanged.

Anything other value will cause an exception to be thrown.

FieldResolver

protocol

added in 0.24.0

Allows a Clojure record to operate as a field resolver.

members

resolve-value

(resolve-value this context args value)

The analog of a field resolver function, this method is passed the instance, and the standard context, field arguments, and container value, and returns a resolved value.

is-resolver-result?

added in 0.23.0

(is-resolver-result? value)

Is the provided value actually a ResolverResult?

resolve-as

(resolve-as resolved-value)(resolve-as resolved-value resolver-error)

Invoked by field resolvers to wrap a simple return value as a ResolverResult.

The two-arguments version is a convenience around using with-error.

This is an immediately realized ResolverResult.

Use resolve-promise and deliver! for an asynchronous result.

When on-deliver! is invoked, the provided callback is immediately invoked (in the same thread).

resolve-promise

(resolve-promise)

Returns a ResolverResultPromise.

At creation, the promise will capture per-thread bindings and ensure they are conveyed to the callback, should the callback be invoked asynchronously (when *callback-executor* is bound to an Executor).

A value must be resolved and ultimately provided via deliver!.

ResolverResult

protocol

A special type returned from a field resolver that can contain a resolved value. A ResolverResult encapsulates the difference between when Lacinia invokes a field resolver function, and when the value computed by that field resolver is ready.

In most cases, a field resolver returns a simple value, which is wrapped by resolve-as into a ResolverResult.

More sophisticated field resolvers can return a ResolverResultPromise (via resolve-promise), and deliver the result’s value asynchronously via deliver!.

members

on-deliver!

(on-deliver! this callback)

Provides a callback that is invoked immediately after the ResolverResult is realized. The callback is passed the ResolverResult’s value.

on-deliver! should only be invoked once. It returns this.

On a simple ResolverResult (not a ResolverResultPromise), the callback is invoked immediately.

For a ResolverResultPromise, the callback may be invoked on another thread. Per-thread bindings in place when on-deliver! is invoked will be restored prior to invoking the callback.

The callback is invoked for side-effects; its result is ignored.

ResolverResultPromise

protocol

A specialization of ResolverResult that supports asynchronous delivery of the resolved value and errors.

These are created by resolve-promise.

members

deliver!

(deliver! this value)(deliver! this value error)

Invoked to realize the ResolverResult, triggering the callback to receive the value.

The callback is invoked in the current thread, unless *thread-pool* is non-nil, in which case the callback is invoked in a pooled thread.

The two arguments version is simply a convenience around the with-error modifier.

Returns this.

with-context

added in 0.19.0

(with-context value context-map)

Wraps a value so that when nested fields (at any depth) are executed, the provided values will be in the context.

The provided context-map is merged onto the application context.

with-error

added in 0.19.0

(with-error value error)

Wraps a value, modifying it to include an error map.

The provided error map will be enhanced with a :location key, identifying where field occurs within the query document, and a :path key, identifying the sequence of fields (or aliases) and list indexes within the :data key of the result map.

Any additional keys in the error map beyond :message (which must be present, and must be a string) will be added to an embedded :extensions map.

with-extensions

added in 0.31.0

(with-extensions value f & args)

Wraps a value with an update to the extensions for the request.

The extensions are a map, and this applies a change to that map, as with clojure.core/update: the function is provided with the current value of the extensions map and the arguments, and returns the new value of the extensions map.

with-warning

added in 0.31.0

(with-warning value warning)

As with with-error, but the error map will be added to the :warnings key of the root :extensions map (not to the root :errors map). Errors should only be used to indicate a substantial failure, whereas warnings are more advisory. It is up to the application to determine what situations call for an error and what call for a warning.

wrap-resolver-result

added in 0.23.0

(wrap-resolver-result resolver wrapper-fn)

Wraps a resolver function or (FieldResolver instance), passing the result through a wrapper function.

The wrapper function is passed four values: the context, arguments, and value as passed to the resolver, then the resolved value from the resolver.

wrap-resolver-result understands resolver functions that return either a ResolverResult or a bare value, as well as values wrapped with a modifier (such as with-error).

The wrapper-fn is passed the underlying value and must return a new value. The new value will be re-wrapped with modifiers as necessary.

The new value returned by the wrapper-fn may itself be a ResolverResult, and the value (either plain, or inside a ResolverResult) may also be modified (via with-error, etc.).

Returns a standard field resolver function, with the standard three parameters (context, args, value).