Table of Contents

Class XapiClient

Namespace
Xapi.Client
Assembly
Xapi.Client.dll

The xAPI resources of one LRS over an HttpClient: Statements, State, Activity Profile, Agent Profile, Agents, Activities and About (IEEE 9274.1.1, 4.1.6). Every request carries the X-Experience-API-Version header and, if configured, credentials.

public class XapiClient
Inheritance
XapiClient
Inherited Members

Remarks

Error responses throw XapiHttpException, or its subclasses XapiConflictException (409) and XapiPreconditionFailedException (412). Methods that fetch one thing by id return null on 404 instead. Network failures and timeouts surface unchanged as HttpRequestException and TaskCanceledException. Nothing is retried.

Responses are read leniently (Lenient): properties the client does not know are ignored.

The client keeps no per-request state and can be shared between threads. The HttpClient is not disposed by the client. Configure timeouts, proxies and handlers on the HttpClient; the transport can be any HttpMessageHandler.

There is no built-in retry. With dependency injection, add one to the HttpClient pipeline; see AddXapiClient. For offline use and guaranteed delivery, use an outbox instead.

The service methods are virtual so that tests can replace them: derive from the class, call the protected constructor XapiClient() and override the methods the code under test calls. Each method stands alone; overriding one does not change what another does.

Constructors

XapiClient()

Creates a client that cannot send anything, for mocking: a test double derived from XapiClient calls this constructor and overrides the methods it needs.

protected XapiClient()

Remarks

The methods that are not overridden throw InvalidOperationException.

XapiClient(HttpClient, XapiClientOptions)

Creates a client.

public XapiClient(HttpClient httpClient, XapiClientOptions options)

Parameters

httpClient HttpClient

The HTTP client to send requests with.

options XapiClientOptions

The settings. They are copied; later changes have no effect.

Exceptions

ArgumentException

Endpoint is missing or not absolute.

Methods

DeleteDocumentAsync(DocumentKey, DocumentPrecondition?, CancellationToken)

Deletes one document.

public virtual Task DeleteDocumentAsync(DocumentKey key, DocumentPrecondition? precondition = null, CancellationToken cancellationToken = default)

Parameters

key DocumentKey

Which document.

precondition DocumentPrecondition

An If-Match condition, to delete only the version last read.

cancellationToken CancellationToken

Cancels the request.

Returns

Task

A task that completes when the LRS has deleted the document.

Exceptions

XapiPreconditionFailedException

The precondition failed.

DeleteStatesAsync(Iri, Agent, Guid?, CancellationToken)

Deletes every State document of an Activity and Agent (and registration).

public virtual Task DeleteStatesAsync(Iri activityId, Agent agent, Guid? registration = null, CancellationToken cancellationToken = default)

Parameters

activityId Iri

The Activity.

agent Agent

The Agent.

registration Guid?

Only the states of this registration; all registrations when null.

cancellationToken CancellationToken

Cancels the request.

Returns

Task

A task that completes when the LRS has deleted the documents.

GetAboutAsync(CancellationToken)

Fetches the About resource: the xAPI versions the LRS supports, and extensions.

public virtual Task<About> GetAboutAsync(CancellationToken cancellationToken = default)

Parameters

cancellationToken CancellationToken

Cancels the request.

Returns

Task<About>

The About object.

GetActivityAsync(Iri, CancellationToken)

Fetches the LRS's definition of an Activity (Activities resource).

public virtual Task<Activity?> GetActivityAsync(Iri activityId, CancellationToken cancellationToken = default)

Parameters

activityId Iri

The Activity id.

cancellationToken CancellationToken

Cancels the request.

Returns

Task<Activity>

The Activity, or null when the LRS answers 404.

GetActivityProfileIdsAsync(Iri, DateTimeOffset?, CancellationToken)

Lists the Activity Profile ids for an Activity.

public virtual Task<IReadOnlyList<string>> GetActivityProfileIdsAsync(Iri activityId, DateTimeOffset? since = null, CancellationToken cancellationToken = default)

Parameters

activityId Iri

The Activity.

since DateTimeOffset?

Only ids of documents stored or changed after this time.

cancellationToken CancellationToken

Cancels the request.

Returns

Task<IReadOnlyList<string>>

The profileId values.

GetAgentProfileIdsAsync(Agent, DateTimeOffset?, CancellationToken)

Lists the Agent Profile ids for an Agent.

public virtual Task<IReadOnlyList<string>> GetAgentProfileIdsAsync(Agent agent, DateTimeOffset? since = null, CancellationToken cancellationToken = default)

Parameters

agent Agent

The Agent.

since DateTimeOffset?

Only ids of documents stored or changed after this time.

cancellationToken CancellationToken

Cancels the request.

Returns

Task<IReadOnlyList<string>>

The profileId values.

GetDocumentAsync(DocumentKey, CancellationToken)

Fetches one State, Activity Profile or Agent Profile document.

public virtual Task<XapiDocument?> GetDocumentAsync(DocumentKey key, CancellationToken cancellationToken = default)

Parameters

key DocumentKey

Which document.

cancellationToken CancellationToken

Cancels the request.

Returns

Task<XapiDocument>

The document with its ETag, or null when the LRS answers 404.

GetMoreStatementsAsync(Uri, CancellationToken)

Fetches the next page of a Statement query.

public virtual Task<StatementResult> GetMoreStatementsAsync(Uri more, CancellationToken cancellationToken = default)

Parameters

more Uri

The More of the previous page.

cancellationToken CancellationToken

Cancels the request.

Returns

Task<StatementResult>

The page.

Remarks

Only the path and query of more are used; they are sent to the scheme, host and port of Endpoint, so credentials never go to another host. A path without a leading slash is resolved against the endpoint.

GetPersonAsync(Agent, CancellationToken)

Fetches the Person object the LRS knows for an Agent (Agents resource).

public virtual Task<Person> GetPersonAsync(Agent agent, CancellationToken cancellationToken = default)

Parameters

agent Agent

The Agent.

cancellationToken CancellationToken

Cancels the request.

Returns

Task<Person>

The Person; at least the identifiers of agent.

GetStateIdsAsync(Iri, Agent, Guid?, DateTimeOffset?, CancellationToken)

Lists the State ids for an Activity and Agent (and registration).

public virtual Task<IReadOnlyList<string>> GetStateIdsAsync(Iri activityId, Agent agent, Guid? registration = null, DateTimeOffset? since = null, CancellationToken cancellationToken = default)

Parameters

activityId Iri

The Activity.

agent Agent

The Agent.

registration Guid?

The registration, if the states are tied to one.

since DateTimeOffset?

Only ids of documents stored or changed after this time.

cancellationToken CancellationToken

Cancels the request.

Returns

Task<IReadOnlyList<string>>

The stateId values.

GetStatementAsync(Guid, StatementFormat, CancellationToken)

Fetches one Statement by id (statementId). Voided Statements are not returned.

public virtual Task<Statement?> GetStatementAsync(Guid id, StatementFormat format = StatementFormat.Exact, CancellationToken cancellationToken = default)

Parameters

id Guid

The Statement id.

format StatementFormat

How much of Agents, Activities and Verbs to return.

cancellationToken CancellationToken

Cancels the request.

Returns

Task<Statement>

The Statement, or null when the LRS answers 404.

GetVersionAsync(CancellationToken)

The xAPI version used for requests: Version, or the version negotiated with the About resource on first use.

public virtual Task<XapiVersion> GetVersionAsync(CancellationToken cancellationToken = default)

Parameters

cancellationToken CancellationToken

Cancels the wait for the negotiation.

Returns

Task<XapiVersion>

The version.

Exceptions

NotSupportedException

The LRS supports neither 2.0.x nor 1.0.x.

GetVoidedStatementAsync(Guid, StatementFormat, CancellationToken)

Fetches one voided Statement by id (voidedStatementId).

public virtual Task<Statement?> GetVoidedStatementAsync(Guid id, StatementFormat format = StatementFormat.Exact, CancellationToken cancellationToken = default)

Parameters

id Guid

The id of the voided Statement (not of the voiding one).

format StatementFormat

How much of Agents, Activities and Verbs to return.

cancellationToken CancellationToken

Cancels the request.

Returns

Task<Statement>

The Statement, or null when the LRS answers 404.

MergeDocumentAsync(DocumentKey, JsonElement, DocumentPrecondition?, CancellationToken)

Merges a JSON object into a document (POST): each top-level property replaces the one in the stored JSON object. Creates the document if it does not exist.

public virtual Task MergeDocumentAsync(DocumentKey key, JsonElement json, DocumentPrecondition? precondition = null, CancellationToken cancellationToken = default)

Parameters

key DocumentKey

Which document.

json JsonElement

A JSON object.

precondition DocumentPrecondition

An If-Match or If-None-Match condition.

cancellationToken CancellationToken

Cancels the request.

Returns

Task

A task that completes when the LRS has stored the result.

Exceptions

ArgumentException

json is not an object.

XapiPreconditionFailedException

The precondition failed.

PutDocumentAsync(DocumentKey, XapiDocument, DocumentPrecondition?, CancellationToken)

Stores a document, replacing any existing one (PUT).

public virtual Task PutDocumentAsync(DocumentKey key, XapiDocument document, DocumentPrecondition? precondition = null, CancellationToken cancellationToken = default)

Parameters

key DocumentKey

Which document.

document XapiDocument

The content and content type. Its ETag and Last-Modified are not sent.

precondition DocumentPrecondition

An If-Match or If-None-Match condition.

cancellationToken CancellationToken

Cancels the request.

Returns

Task

A task that completes when the LRS has stored the document.

Remarks

Without a precondition, xAPI 2.0 LRSs answer 409 when the document already exists (IEEE 9274.1.1, 4.1.4). Use IfNoneMatchAny to create and IfMatch(string) to replace.

Exceptions

XapiPreconditionFailedException

The precondition failed.

XapiConflictException

The document exists and no precondition was sent.

QueryAllStatementsAsync(StatementQuery, CancellationToken)

Runs a Statement query and follows more until the last page, one page request at a time.

public virtual IAsyncEnumerable<Statement> QueryAllStatementsAsync(StatementQuery query, CancellationToken cancellationToken = default)

Parameters

query StatementQuery

Filters and options.

cancellationToken CancellationToken

Cancels the enumeration.

Returns

IAsyncEnumerable<Statement>

Every matching Statement.

Remarks

Attachment data is not returned; use QueryStatementsAsync(StatementQuery, CancellationToken) for that.

QueryStatementsAsync(StatementQuery, CancellationToken)

Fetches the first page of a Statement query.

public virtual Task<StatementResult> QueryStatementsAsync(StatementQuery query, CancellationToken cancellationToken = default)

Parameters

query StatementQuery

Filters and options.

cancellationToken CancellationToken

Cancels the request.

Returns

Task<StatementResult>

The page; follow More with GetMoreStatementsAsync(Uri, CancellationToken).

SaveStatementAsync(Statement, IReadOnlyList<AttachmentPayload>?, CancellationToken)

Stores one Statement: PUT with statementId when Id is set, POST otherwise.

public virtual Task<Guid> SaveStatementAsync(Statement statement, IReadOnlyList<AttachmentPayload>? attachments = null, CancellationToken cancellationToken = default)

Parameters

statement Statement

The Statement.

attachments IReadOnlyList<AttachmentPayload>

Data for the Statement's Attachments that have no fileUrl. When there is any, the request is sent as multipart/mixed.

cancellationToken CancellationToken

Cancels the request.

Returns

Task<Guid>

The Statement id: Id, or the id the LRS assigned.

Exceptions

XapiValidationException

The Statement is invalid and ValidateBeforeSend is on.

XapiConflictException

The LRS has a different Statement with the same id.

SaveStatementsAsync(IReadOnlyList<Statement>, IReadOnlyList<AttachmentPayload>?, CancellationToken)

Stores a batch of Statements with one POST. The LRS stores all or none of them.

public virtual Task<IReadOnlyList<Guid>> SaveStatementsAsync(IReadOnlyList<Statement> statements, IReadOnlyList<AttachmentPayload>? attachments = null, CancellationToken cancellationToken = default)

Parameters

statements IReadOnlyList<Statement>

The Statements.

attachments IReadOnlyList<AttachmentPayload>

Data for Attachments that have no fileUrl, in any of the Statements.

cancellationToken CancellationToken

Cancels the request.

Returns

Task<IReadOnlyList<Guid>>

The Statement ids, in the order of statements.

Remarks

An empty batch returns an empty list without a request.

Exceptions

XapiValidationException

A Statement is invalid, or two share an id, and ValidateBeforeSend is on.

XapiConflictException

The LRS has a different Statement with the id of one in the batch.

VoidStatementAsync(Guid, Actor, CancellationToken)

Voids a Statement by storing a Statement with the voided Verb and a StatementRef to it.

public virtual Task<Guid> VoidStatementAsync(Guid statementId, Actor actor, CancellationToken cancellationToken = default)

Parameters

statementId Guid

The id of the Statement to void.

actor Actor

Who voids it.

cancellationToken CancellationToken

Cancels the request.

Returns

Task<Guid>

The id of the voiding Statement.

Remarks

IEEE 9274.1.1, 4.2.5. The voided Statement is then only returned by GetVoidedStatementAsync(Guid, StatementFormat, CancellationToken).