pub struct Client<C, M, R = Standard> { /* private fields */ }
Expand description

An ergonomic service client for IdentityService.

This client allows ergonomic access to a IdentityService-shaped service. Each method corresponds to an endpoint defined in the service’s Smithy model, and the request and response shapes are auto-generated from that same model.

Constructing a Client

To construct a client, you need a few different things:

  • A Config that specifies additional configuration required by the service.
  • A connector (C) that specifies how HTTP requests are translated into HTTP responses. This will typically be an HTTP client (like hyper), though you can also substitute in your own, like a mock mock connector for testing.
  • A “middleware” (M) that modifies requests prior to them being sent to the request. Most commonly, middleware will decide what endpoint the requests should be sent to, as well as perform authentication and authorization of requests (such as SigV4). You can also have middleware that performs request/response tracing, throttling, or other middleware-like tasks.
  • A retry policy (R) that dictates the behavior for requests that fail and should (potentially) be retried. The default type is generally what you want, as it implements a well-vetted retry policy implemented in RetryMode::Standard.

To construct a client, you will generally want to call Client::with_config, which takes a aws_smithy_client::Client (a Smithy client that isn’t specialized to a particular service), and a Config. Both of these are constructed using the builder pattern where you first construct a Builder type, then configure it with the necessary parameters, and then call build to construct the finalized output type. The aws_smithy_client::Client builder is re-exported in this crate as Builder for convenience.

In most circumstances, you will want to use the following pattern to construct a client:

use rivet_identity::{Builder, Client, Config};
let raw_client =
    Builder::dyn_https()
      .middleware(/* discussed below */)
      .build();
let config = Config::builder().build();
let client = Client::with_config(raw_client, config);

For the middleware, you’ll want to use whatever matches the routing, authentication and authorization required by the target service. For example, for the standard AWS SDK which uses SigV4-signed requests, the middleware looks like this:

use aws_endpoint::AwsEndpointStage;
use aws_http::auth::CredentialsStage;
use aws_http::recursion_detection::RecursionDetectionStage;
use aws_http::user_agent::UserAgentStage;
use aws_sig_auth::middleware::SigV4SigningStage;
use aws_sig_auth::signer::SigV4Signer;
use aws_smithy_client::retry::Config as RetryConfig;
use aws_smithy_http_tower::map_request::{AsyncMapRequestLayer, MapRequestLayer};
use std::fmt::Debug;
use tower::layer::util::{Identity, Stack};
use tower::ServiceBuilder;

type AwsMiddlewareStack = Stack<
    MapRequestLayer<RecursionDetectionStage>,
    Stack<
        MapRequestLayer<SigV4SigningStage>,
        Stack<
            AsyncMapRequestLayer<CredentialsStage>,
            Stack<
                MapRequestLayer<UserAgentStage>,
                Stack<MapRequestLayer<AwsEndpointStage>, Identity>,
            >,
        >,
    >,
>;

/// AWS Middleware Stack
///
/// This implements the middleware stack for this service. It will:
/// 1. Load credentials asynchronously into the property bag
/// 2. Sign the request with SigV4
/// 3. Resolve an Endpoint for the request
/// 4. Add a user agent to the request
#[derive(Debug, Default, Clone)]
#[non_exhaustive]
pub struct AwsMiddleware;

impl AwsMiddleware {
    /// Create a new `AwsMiddleware` stack
    ///
    /// Note: `AwsMiddleware` holds no state.
    pub fn new() -> Self {
        AwsMiddleware::default()
    }
}

// define the middleware stack in a non-generic location to reduce code bloat.
fn base() -> ServiceBuilder<AwsMiddlewareStack> {
    let credential_provider = AsyncMapRequestLayer::for_mapper(CredentialsStage::new());
    let signer = MapRequestLayer::for_mapper(SigV4SigningStage::new(SigV4Signer::new()));
    let endpoint_resolver = MapRequestLayer::for_mapper(AwsEndpointStage);
    let user_agent = MapRequestLayer::for_mapper(UserAgentStage::new());
    let recursion_detection = MapRequestLayer::for_mapper(RecursionDetectionStage::new());
    // These layers can be considered as occurring in order, that is:
    // 1. Resolve an endpoint
    // 2. Add a user agent
    // 3. Acquire credentials
    // 4. Sign with credentials
    // (5. Dispatch over the wire)
    ServiceBuilder::new()
        .layer(endpoint_resolver)
        .layer(user_agent)
        .layer(credential_provider)
        .layer(signer)
        .layer(recursion_detection)
}

impl<S> tower::Layer<S> for AwsMiddleware {
    type Service = <AwsMiddlewareStack as tower::Layer<S>>::Service;

    fn layer(&self, inner: S) -> Self::Service {
        base().service(inner)
    }
}

Using a Client

Once you have a client set up, you can access the service’s endpoints by calling the appropriate method on Client. Each such method returns a request builder for that endpoint, with methods for setting the various fields of the request. Once your request is complete, use the send method to send the request. send returns a future, which you then have to .await to get the service’s response.

Implementations

Creates a client with the given service configuration.

Returns the client’s configuration.

Constructs a fluent builder for the CompleteGameLink operation.

Constructs a fluent builder for the CompleteIdentityAvatarUpload operation.

Constructs a fluent builder for the FollowIdentity operation.

Constructs a fluent builder for the GetGameLink operation.

Constructs a fluent builder for the GetIdentityProfile operation.

Constructs a fluent builder for the GetIdentitySelfProfile operation.

Constructs a fluent builder for the ListActivities operation.

Constructs a fluent builder for the ListFollowers operation.

Constructs a fluent builder for the ListFollowing operation.

Constructs a fluent builder for the ListFriends operation.

Constructs a fluent builder for the PrepareGameLink operation.

Constructs a fluent builder for the PrepareIdentityAvatarUpload operation.

Constructs a fluent builder for the RemoveIdentityGameActivity operation.

Constructs a fluent builder for the SearchIdentities operation.

Constructs a fluent builder for the SetIdentityGameActivity operation.

Constructs a fluent builder for the SetupIdentity operation.

  • The fluent builder is configurable:
  • On success, responds with SetupIdentityOutput with field(s):
    • identity_token(Option<String>): Token used to authenticate the identity. Should be stored somewhere permanent. Pass this to rivet.api.identity#SetupIdentity$existing_identity_token next time rivet.api.identity#SetupIdentity is called. Token has a 90 day TTL. This means that if rivet.api.identity#SetupIdentity is not called again within 90 days, the token will no longer be valid. If this happens, the user can recover their account through the linking process (see rivet.api.identity#PrepareGameLink). This token should be stored locally and never sent to a server or another device. If this token is comprimised, anyone with access to this token has control of the identity.
    • identity_token_expire_ts(Option<DateTime>): Timestamp (in milliseconds) at which the token expires.
    • identity(Option<IdentityProfile>): Information about the identity that was just authenticated.
  • On failure, responds with SdkError<SetupIdentityError>

Constructs a fluent builder for the SignupForBeta operation.

Constructs a fluent builder for the UnfollowIdentity operation.

Constructs a fluent builder for the UpdateIdentityProfile operation.

Constructs a fluent builder for the UpdateIdentityStatus operation.

Constructs a fluent builder for the ValidateIdentityProfile operation.

Constructs a fluent builder for the WatchEvents operation.

Trait Implementations

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Formats the value using the given formatter. Read more

Converts to this type from the input type.

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more

Instruments this type with the current Span, returning an Instrumented wrapper. Read more

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The resulting type after obtaining ownership.

Creates owned data from borrowed data, usually by cloning. Read more

Uses borrowed data to replace owned data, usually by cloning. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more