From dd2cc72eed7a5a21319ef7102816b272d6041454 Mon Sep 17 00:00:00 2001 From: Hunter Mellema Date: Fri, 14 Feb 2025 09:10:16 -0700 Subject: [PATCH 01/18] Add client user guide for smithy java --- .../java/client/codegen-integrations.rst | 80 +++ docs/source-2.0/java/client/configuration.rst | 506 ++++++++++++++++++ docs/source-2.0/java/client/customization.rst | 127 +++++ .../source-2.0/java/client/dynamic-client.rst | 69 +++ .../java/client/generating-clients.rst | 201 +++++++ docs/source-2.0/java/client/index.rst | 24 + docs/source-2.0/java/client/plugins.rst | 121 +++++ docs/source-2.0/java/index.rst | 1 + 8 files changed, 1129 insertions(+) create mode 100644 docs/source-2.0/java/client/codegen-integrations.rst create mode 100644 docs/source-2.0/java/client/configuration.rst create mode 100644 docs/source-2.0/java/client/customization.rst create mode 100644 docs/source-2.0/java/client/dynamic-client.rst create mode 100644 docs/source-2.0/java/client/generating-clients.rst create mode 100644 docs/source-2.0/java/client/index.rst create mode 100644 docs/source-2.0/java/client/plugins.rst diff --git a/docs/source-2.0/java/client/codegen-integrations.rst b/docs/source-2.0/java/client/codegen-integrations.rst new file mode 100644 index 00000000000..5c50bec6ef8 --- /dev/null +++ b/docs/source-2.0/java/client/codegen-integrations.rst @@ -0,0 +1,80 @@ +==================== +Codegen Integrations +==================== + +Smithy Java provides a number of client codegen integrations that modify the code generated by the client codegen plugin. + +-------------- +Waiter Codegen +-------------- + +.. warning:: + + Only synchronous waiters are supported at this time. + +:ref:`Waiters ` are a client-side abstraction used to poll a resource until a desired state is reached, +or until it is determined that the resource will never enter a desirable end state. +Waiters can be defined in the Smithy model using the ``smithy.waiters#waitable`` trait. + +For example: + +.. code-block:: smithy + :caption: model.smithy + + use smithy.waiters#waitable + + @waitable( + BucketExists: { + documentation: "Wait until a bucket exists" + acceptors: [ + { + state: "success" + matcher: { + success: true + } + } + { + state: "retry" + matcher: { + errorType: "NotFound" + } + } + ] + } + ) + operation HeadBucket { + input: HeadBucketInput + output: HeadBucketOutput + errors: [NotFound] + } + +The waiter-codegen integration can be used to automatically generate waiters from waitable trait +definitions in your Smithy model. To add the integration to your project (using the Smithy Gradle plugins): + +.. code-block:: kotlin + :caption: build.gradle.kts + + dependencies { + // Add codegen integration as a smithy-build dependency so it can be + // discovered by the client codegen plugin + smithyBuild("software.amazon.smithy.java.codegen:waiters:__smithy_java_version__") + + // Add waiters core package as a runtime dependency + implementation("software.amazon.smithy.java:waiters:__smithy_java_version__") + } + +This will cause your client code generator to create a waiter container class call ``Waiters`` +in your generated client package. This container provides a method per waiter defined in your smithy model +that returns a pre-configured ``Waiter``` instance base on the configuration set in your Smithy model. + +You can get an instance of this waiter container for a client by calling the ``waiters()`` method added +to clients by this integration. + +.. code-block:: java + + // Get the generated waiter container + var waiters = client.waiters(); + // Get the configurable waiter from the container + var orderCompletedWaiter = waiters.orderCompleted(); + // Wait for up to 2 seconds for the waiter to complete. + orderCompletedWaiter.wait(input, Duration.ofSeconds(2); diff --git a/docs/source-2.0/java/client/configuration.rst b/docs/source-2.0/java/client/configuration.rst new file mode 100644 index 00000000000..1949f14fc75 --- /dev/null +++ b/docs/source-2.0/java/client/configuration.rst @@ -0,0 +1,506 @@ +=================== +Configuring Clients +=================== + +Generated Smithy Java clients are composed of a number of runtime-configurable components: + +* :ref:`Protocols ` - Defines how to serialize and deserialize a client request. +* :ref:`Transports ` - Manages connections and the sending of data on the wire. +* :ref:`Auth Schemes ` - Add authentication/authorization information to a client request. +* :ref:`Endpoint Resolvers ` - Resolves the service endpoint to call. +* :ref:`Context Properties ` - Set typed properties on the client. + +.. _java-client-protocols: + +--------- +Protocols +--------- + +A protocol defines how to (de)serialize and bind data into a request. For example, an HTTP+JSON protocol +would handle the serialization of data into the HTTP message body as JSON and might bind some data to the +HTTP message headers. + +Configure a protocol +^^^^^^^^^^^^^^^^^^^^ + +The Smithy IDL is protocol-agnostic and allows a service to support any number of protocols for transport and +(de)serialization of data. Like the Smithy IDL, Smithy Java clients are also protocol-agnostic and allow users +to configure a protocol at runtime. + +To set a protocol at runtime, add the protocol to the client builder as follows: + +.. code-block:: java + :caption: Set protocol at runtime + + var client = MyGeneratedClient.builder() + .protocol(new MyProtocol()) + .build(); + +.. admonition:: Important + :class: note + + The input/output types of the configured protocol must be compatible with the configured transport. + +Set a default protocol +^^^^^^^^^^^^^^^^^^^^^^ + +While users may want to set a different protocol at runtime, it is typically desirable for generated clients to have a default protocol that can be used without any client configuration. + +To configure the client code generation plugin to set a default protocol, add the protocol’s fully qualified Smithy ID to the protocol setting in the smithy-build.json configuration file. + +.. code-block:: json + :caption: smithy-build.json + + "plugins": { + "java-client-codegen": { + // Set the default protocol for the client. + "protocol": "smithy.protocols#rpcv2Cbor", + // ... additional settings + } + } + +All protocols used for your service SHOULD use have an associated protocol trait applied to the service shape. +For example to use the rpcv2 protocol with your service you would add the associated protocol trait to your Smithy model: + +.. code-block:: smithy + :caption: model.smithy + + @rpcV2Cbor // <- Protocol trait + service MyService() + +.. tip:: + + The built-in rpcv2-cbor protocol is a generic binary protocol provided by Smithy Java that can be a + good choice for services that want a fast, compact data format. + +Provided protocols +^^^^^^^^^^^^^^^^^^ + +The Smithy Java framework provides the following pre-built protocols: + +.. list-table:: + :header-rows: 1 + :widths: 20 5 30 35 10 + + * - Name + - Type + - Trait + - Description + - Package + * - rpcv2Cbor + - Smithy + - ``smithy.protocols#rpcv2Cbor`` + - RPC-based protocol over HTTP that sends requests and responses with CBOR payloads. + - ``client-rpcv2-cbor`` + * - AWS JSON 1.1 + - AWS + - ``aws.protocols#awsJson1_1`` + - HTTP protocol that sends "POST" requests and responses with JSON documents. + - ``aws-client-awsjson`` + * - AWS Rest JSON 1.0 + - AWS + - ``aws.protocols#restJson1`` + - HTTP-based protocol that sends JSON requests and responses + - ``aws-client-awsjson`` + * - AWS Rest XML + - AWS + - ``aws.protocols#restXml`` + - HTTP-based protocol that sends XML requests and responses + - ``aws-client-restxml`` + +Writing custom protocols +^^^^^^^^^^^^^^^^^^^^^^^^^ + +To create a custom protocol, implement the ``ClientProtocol`` interface from the client-core package. + +.. tip:: + + If you are writing a service that uses a custom HTTP protocol, you can extend the HttpClientProtocol + and use one of the codecs provided by Smithy Java to get started. + +Default protocols are discovered via Service Provider Interface (SPI). To use a custom protocol as a default, you +must implement a protocol factory that implements ``ClientProtocolFactory``. +Once you have defined your factory, add it’s fully qualified name to the service provider file +(``META-INF/services/software.amazon.smithy.java.runtime.client.core.ClientProtocolFactory``). +A default protocol must have a corresponding protocol trait applied to the service shape being generated. + +Smithy Java codec‘s are used by both client and server protocols for generic (de)serialization of generated types into wire data such as JSON. +Protocols SHOULD use an appropriate codec for (de)serialization where possible. Smithy-Java provides XML, JSON, and CBOR codecs. + +When writing a custom protocol, we recommend writing compliance tests that can be used to validate the protocol across +multiple language implementations. The ``protocol-test-harness`` package provides a JUnit5 test harness for +running protocol compliance tests with Smithy Java. + +.. _java-client-transports: + +---------- +Transports +---------- + +Transports manages connections, and handle the sending/receiving of serialized requests/responses. + +``ClientTransport``'s can also configure default functionality like adding a user-agent header for HTTP request +by modifying the client builder using the ``configureClient`` method. + +.. admonition:: Important + :class: note + + When overriding the configureClient method of a ClientTransport, you need to also call the configureClient + method of the ``MessageExchange``, if you want it to take effect. This allows for transports to override + or even completely remove ``MessageExchange``-wide functionality. + +Transport Discovery +^^^^^^^^^^^^^^^^^^^ + +Transport implementations can be automatically discovered by client code generators and dynamic clients via SPI. +To make a transport implementation discoverable, implement the ``ClientTransportFactory`` service provider. + +If no transport is set on a client, the client will attempt to resolve a transport compatible with the current protocol +from the discoverable transport implementations. + +Setting a default transport +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To set a default, add the following to your :ref:`smithy-build.json `: + +.. code-block:: json + :caption: smithy-build.json + + "java-client-codegen": { + //... + "transport": { + "http-java": {} + } + } + +.. admonition:: Important + :class: note + + Transports set as the default still need to implement the ``ClientTransportFactory`` service provider to + be discoverable by the code generation plugin. + +Provided transports +^^^^^^^^^^^^^^^^^^^ + +* **http-java** - Uses the ``java.net.http.HttpClient`` to send and receive HTTP messages. + This transport is provided by the ``client-http`` module. + + +.. _java-client-authSchemes: + +------------ +Auth Schemes +------------ + +Auth schemes add authentication/authorization information to a client request. The composition of Auth schemes includes: + +1. Scheme ID - A unique identifier for the authentication scheme that should correspond to the ID of a Smithy trait defining an auth scheme (see: https://smithy.io/2.0/spec/authentication-traits.html#smithy-api-authdefinition-trait) +2. Identity resolver - An API to acquire the customer's identity +3. Signer - An API to sign requests using the resolved identity. + +Auth Schemes can be manually registered on a client at runtime or can be automatically registered by the client code generation plugin. To register an auth scheme at runtime: + +.. code-block:: java + + var client = MyClient.builder() + .putSupportedAuthSchemes(new MyAuthScheme()) + .build() + +Automatic registration +^^^^^^^^^^^^^^^^^^^^^^ + +The Client code generation plugin can discover Auth Schemes on the classpath. If a discovered auth scheme’s ID matches +an auth scheme ID in the Smithy model it will be automatically registered in the generated client. + +To add an auth scheme automatically to a generated client based on a trait in the model, the auth scheme must provided +an ``AuthSchemeFactory`` implementation and register that implementation via SPI. Smithy Java client codegen will +automatically search the classpath for relevant ``AuthSchemeFactory``` implementations and attempt to match those with +a corresponding trait in the model. + +Effective Auth schemes +^^^^^^^^^^^^^^^^^^^^^^ + +Operations may have one or more “effective auth schemes” that could be used to authenticate a request. +Auth scheme traits applied to the service shape are inherited by all service operations unless those +operations have the auth trait applied. + +The ``@auth`` trait define a priority-ordered list of authentication schemes supported by a service or operation. +When applied to a service, it defines the default authentication schemes of every operation in the service. +When applied to an operation, it defines the list of all authentication schemes supported by the operation, +overriding any auth trait specified on a service. + +.. code-block:: smithy + :caption: model.smithy + + @httpBasicAuth + @httpDigestAuth + @httpBearerAuth + service MyService { + version: "2020-01-29" + operations: [ + OperationA + OperationB + ] + } + + // This operation does not have the @auth trait and is bound to a service + // without the @auth trait. The effective set of authentication schemes it + // supports are: httpBasicAuth, httpDigestAuth and httpBearerAuth + operation OperationA {} + + // This operation does have the @auth trait and is bound to a service + // without the @auth trait. The effective set of authentication schemes it + // supports are: httpDigestAuth. + @auth([httpDigestAuth]) + operation OperationB {} + +https://smithy.io/2.0/spec/authentication-traits.html#smithy-api-auth-trait +See :ref:`Auth trait ` for a more thorough discussion on how auth schemes are resolved. + +Identity resolution +^^^^^^^^^^^^^^^^^^^ + +To use an auth-scheme in a client, the client must register a corresponding identity resolver +that provides a compatible identity class. Auth schemes can provide a default resolver themselves +or clients can register resolvers via the client builder or via a client plugin. + +.. tip:: + + Multiple Identity resolvers can be chained together using the IdentityResolver.chain method. + +Provided Auth Schemes +^^^^^^^^^^^^^^^^^^^^^ + +A number of auth schemes are provided by default in the client-http package. These include: + +* :ref:`httpBearerAuth ` - Supports HTTP Bearer Authentication as defined in RFC 6750. +* :ref:`httpApiKeyAuth ` - Supports HTTP authentication using an API key sent in a header or query string parameter. +* :ref:`httpBasicAuth ` - Indicates that a service supports HTTP Basic Authentication as defined in RFC 2617. + +Add the ``client-http`` package as a dependency of your project to make these auth schemes available in your service. + +Worked Example: Adding HTTP API Key Authentication +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Consider a Smithy modeled API for a service, ``ExampleService``. We would like to enable users of our generated SDK +to authenticate to the API using an API key sent via an ``x-api-key`` HTTP header. +Smithy Java already provides an ``httpApiKeyAuth`` Auth Scheme that we can use to allow +this API Key authentication. + +Before we can add any Auth Scheme implementations to our generated client we must first add the associated +:ref:`@httpApiKeyAuth ` scheme trait to our service model. + +.. code-block:: smithy + :caption: model.smithy + + namespace com.example + + @httpApiKeyAuth(name: "X-Api-Key", in: "header") // <- Add auth scheme trait + service ExampleService { + version: "2025-05-05" + // ... + } + +Authentication schemes are effectively part of your services interface and so (outside of testing) +SHOULD always be modeled in your Smithy model using a trait. See the auth definition trait for more information +on how to define a custom auth scheme in your Smithy model. + +Now that we have added our auth trait to the Smithy model we need to add a corresponding AuthScheme implementation +to our client’s dependencies. The client-http package provides an ``HttpApiKeyAuthScheme`` implementation corresponding +to the @httpApiKeyAuth trait. + +.. code-block:: kotlin + :caption: build.gradle.kts + + dependencies { + // Add the HTTP auth scheme to the classpath + implementation("software.amazon.smithy.java:client-http:__smithy_java_version__") + // ... + } + +The ``HttpApiKeyAuthScheme`` class implements the ``AuthSchemeFactory`` service provider, making the auth scheme +discoverable by the client codegen plugin. + +The built-in Smithy Java HTTP auth schemes all require one or more compatible ``IdentityResolver`` +to be register with the client. This resolver will handle actually fetching the clients credentials. +The ``HttpApiKeyAuthScheme`` scheme needs an identity resolver that returns an ``ApiKeyIdentity``. +For testing purposes we will provide a static resolver as follows: + +.. code-block:: java + + var client = ExampleService.builder() + .addIdentityResolver( + IdentityResolver.of(new ApiKeyIdentity.create("example-api-key") + ) + .build() + +Or, we could create a custom resolver that resolves the ``ApiKeyIdentity`` from an environment variable, ``EXAMPLE_API_KEY``: + +.. code-block:: java + :caption: Environment variable identity resolver implementation + + public final class EnvironmentVariableIdentityResolver implements IdentityResolver { + private static final String API_KEY_PROPERTY = "EXAMPLE_API_KEY" + + @Override + public Class identityType() { + return ApiKeyIdentity.class; + } + + @Override + public CompletableFuture> resolveIdentity(AuthProperties requestProperties) { + String apiKey = System.getenv(API_KEY_PROPERTY); + + if (apiKey == null || apiKey.isEmpty()) + return CompletableFuture.completedFuture( + IdentityResult.ofError(getClass(), "Could not find API KEY") + ); + } + + return CompletableFuture.completedFuture(IdentityResult.of(ApiKeyIdentity.create(apiKey))); + } + +Smithy Java also allows identity resolvers to be chained together if we want to check multiple locations for the client. + +.. code-block:: java + :caption: Chaining identity resolvers + + IdentityResolver.chain(List.of(new FirstResolver(), new SecondResolver()) + +.. _java-client-endpoints: + +----------------- +Endpoint Resolver +----------------- + +Endpoint resolvers determine the endpoint to use for an operation. For example, an endpoint resolver could + determine what subdomain to use, i.e. ``us-east-2.myservice.com`` based on a region setting on the client. + +To set a static endpoint for a client use the following client builder setter: + +.. code-block:: java + + client.builder() + .endpointResolver(EndpointResolver.staticResolver("https://example.com")) + .build() + +.. tip:: + + Create a common endpoint resolver for your organization that can be shared across clients. + +.. _java-client-context: + +------------------- +Context Properties +------------------- + +Smithy Java clients allow users to add any configurations to a typed property bag, via the putConfig method. +The properties are tied to a typed key and used by client pipeline components such as request signers. + +For example, a ``REGION`` property might need to be set on the client in order for a ``Sigv4`` request signer to correctly function. +Configuration parameters can be set on a client using a typed property key via the putConfig method: + +.. code-block:: java + :caption: Setting REGION context property + + static Context.Key MY_PROPERTY = Context.key("a config property"); + + ... + + var client = MyClient.builder() + .putContext(MY_PROPERTY, "value") + .build(); + +Custom Builder Setters +^^^^^^^^^^^^^^^^^^^^^^ + +For common settings on a client, it is often desirable to use specifically-named setter methods such as .region("us-east-1") +rather than requiring users to know the specific context property to use for a configuration parameter. +The ``ClientSetting`` interface can be used to create a custom setter that for client builders. + +For example we would write a custom setting as: + +.. code-block:: java + :caption: custom client setting implementation + + public interface CustomSetting> extends ClientSetting { + Context.Key MY_PROPERTY = Context.key("A custom string configuration property"); + + default B custom(String custom) { + // ADD ANY VALIDATION OF THE VALUE HERE + return putConfig(MY_PROPERTY, custom); + } + } + +.. tip:: + + If a config property is required, make sure to validate that it exists using a default plugin (see below) + +A client setting can then be added to our generated clients using the defaultSettings setting in the smithy-build.json file: + +.. code-block:: json + :caption: smithy-build.json + + "java-client-codegen": { + //... + "defaultSettings": [ + "com.example.settings.CustomSetting" + ], + //... + } + +Now we can use our new setting as follows: + +.. code-block:: java + + var client = MyClient.builder() + .custom("that was easy!") + .build(); + +.. tip:: + + Default settings are typically paired with a default plugin to add the configuration and behavior of a feature + (respectively) to a client by default. + +Composing Settings +^^^^^^^^^^^^^^^^^^ + +Some features require multiple custom settings. Because custom settings are simply Java interfaces, we can compose them. + +For example, the SigV4 Auth scheme requires that a region setting and clock setting be set on a client as well +as an additional settings, the signing name of the service. We can define the ``SigV4Settings`` interface as follows: + +.. code-block:: java + :caption: composed setting + + public interface SigV4Settings> + extends ClockSetting, RegionSetting { + + /** + * Service name to use for signing. For example {@code lambda}. + */ + Context.Key SIGNING_NAME = Context.key("Signing name to use for computing SigV4 signatures."); + + /** + * Signing name to use for the SigV4 signing process. + * + *

The signing name is typically the name of the service. For example {@code "lambda"}. + * + * @param signingName signing name. + */ + default B signingName(String signingName) { + // Validation of the signing name + if (signingName == null || signingName.isEmpty()) { + throw new IllegalArgumentException("signingName cannot be null or empty"); + } + return putConfig(SIGNING_NAME, signingName); + } + } + +When the ``SigV4Settings`` interface is added to the codegen configuration as a default setting it will also add the +``ClockSetting`` and ``RegionSetting`` setters to the generated client’s builder. + +.. tip:: + + Create a custom setting class for your organization that aggregates all common settings for your clients. This minimizes the number of code generation configurations you need to provide to create a functional client. Add new settings to the aggregate setting to add them to clients without changing the codegen configuration. + diff --git a/docs/source-2.0/java/client/customization.rst b/docs/source-2.0/java/client/customization.rst new file mode 100644 index 00000000000..ea9f026faf3 --- /dev/null +++ b/docs/source-2.0/java/client/customization.rst @@ -0,0 +1,127 @@ +=========================== +Customizing Client Behavior +=========================== + +Request-Level Overrides +----------------------- + +Smithy Java supports client configuration overrides that are applied to a single request. Create and use an override as follows: + +.. code-block:: java + + var requestOverride = RequestOverrideConfig.builder() + .protocol(...) + .addIdentityResolver(...) + // etc... + .build() + + var fooOutput = client.callFoo(fooInput, requestOverride); + +Each generated client will also generate a client-specific ``RequestOverride`` class that includes any custom +configuration settings. To get a client-specific override builder use the ``.requestOverrideBuilder`` on the +generated client: + +.. code-block:: java + + var overrideBuilder = MyClient.requestOverrideBuilder(); + var override = overrideBuilder.customSetting("foo").build(); + var output = client.createFoo(input, override); + +Interceptors +------------ + +Interceptors allow “injecting” logic into specific stages of the request execution pipeline. +Logic injection is done with hooks that the interceptor implements. + +The following hooks are supported: + +* **readBeforeExecution** - called at the start of an execution, before the client does anything else +* **modifyBeforeSerialization** - called before the input message is serialized into a transport message +* **readBeforeSerialization** - called before the input is serialized into a transport request +* **readAfterSerialization** - called after the input message is marshalled into a protocol-specific request +* **modifyBeforeRetryLoop** - called before the retry loop is entered that can be used to modify and return a new request +* **readBeforeAttempt** - called before each attempt at sending the transmission * request message to the service. +* **modifyBeforeSigning** - called before the request is signed; this method can modify and return a new request +* **readBeforeSigning** - called before the transport request message is signed +* **readAfterSigning** - called after the transport request message is signed +* **modifyBeforeTransmit** - called before the transport request message is sent to the service +* **readBeforeTransmit** - called before the transport request message is sent to the * service +* **readAfterTransmit** - called after the transport request message is sent to the service and a transport response message is received +* **modifyBeforeDeserialization** - hook called before the response is deserialized +* **readBeforeDeserialization** - called before the response is deserialized +* **readAfterDeserialization** - called after the transport response message is deserialized +* **modifyBeforeAttemptCompletion** - hook called when an attempt is completed. This method can modify and return a new output or error matching the currently executing operation +* **readAfterAttempt** - hook called when an attempt is completed +* **modifyBeforeCompletion** - hook called when an execution is completed +* **readAfterExecution** - called when an execution is completed + +Interceptors implement the ``ClientInterceptor`` interface and override one or more hook methods. + +Interceptors can be registered for all calls on a client: + +.. code-block:: java + + var client = MyClient.builder() + .addInterceptor(new MyInterceptor()) + .build(); + +Or for a single request: + +.. code-block:: java + + var requestOverride = RequestOverrideConfig.builder() + .addInterceptor(new MyInterceptor()) + .build() + + var fooOutput = client.callFoo(fooInput, requestOverride); + +Plugins +------- + +Plugins implement the ``ClientPlugin`` interface to modify client configuration when the client is created or when +an operation is called (if added to a ``RequestOverrideConfig``). + +Plugins set IdentityResolvers, EndpointResolvers, Interceptors, AuthSchemeResolvers, +and other client configuration in a repeatable way. + +.. tip:: + + Create one or more common plugins for your organization to apply a standard configuration to generated clients. + + +To apply a plugins to a client at runtime use the addPlugin method on the client builder: + +.. code-block:: java + + var client = MyClient.builder() + .addPlugin(new MyPlugin()) + .build(); + +.. admonition:: Important + :class: note + + Plugins are run only at client build time if added to the client builder or once before executing a call if they are included in a RequestOverrideConfig. + +Default Plugins +^^^^^^^^^^^^^^^ + +Plugins can be applied by default at client instantiation. To apply a plugin by default , add the plugin’s +fully qualified name to the ``defaultPlugins``` setting to your :ref`smithy-build ` configuration: + +.. code-block:: json + :caption: smithy-build.json + + "java-client-codegen": { + // ... + "defaultPlugins": [ + "fully.qualified.plugin.name.MyPlugin" + ] + } + +.. admonition:: Important + :class: note + + Because default plugins need to be instantiated with no user input they must have a public, + zero-arg constructor defined. The code generator will check for an empty constructor when + resolving default plugins and fail if none is found. + diff --git a/docs/source-2.0/java/client/dynamic-client.rst b/docs/source-2.0/java/client/dynamic-client.rst new file mode 100644 index 00000000000..426ed984a7b --- /dev/null +++ b/docs/source-2.0/java/client/dynamic-client.rst @@ -0,0 +1,69 @@ +============== +Dynamic Client +============== + +The dynamic client is used to interact with services more without a code-generated client. The dynamic client loads Smithy models at runtime, converting them to a schema-based client. Users can call a modeled service using document types as input and output. + +.. warning:: + + The dynamic client currently does not currently support streaming or event streaming. + +Usage +----- + +Add the dynamic-client module as a dependency of your project: + +.. code-block:: kotlin + :caption: build.gradle.kts + + dependencies { + implementation("software.amazon.smithy.java:dynamicclient:__smithy_java_version__") + } + +Then, load the Smithy model for use by the dynamic client. + +.. code-block:: java + + import software.amazon.smithy.java.dynamicclient + import software.amazon.smithy.model.Model; + ... + + var model = Model.assembler() + .addImport("/path/to/model.json") + .assemble() + .unwrap(); + +Then, select the service to call, this should be a service shape in the loaded model, +in this case a ``CoffeeShop`` service. + +.. code-block:: java + + var shapeId = ShapeId.from("com.example#CoffeeShop"); + +Now, create the ``DynamicClient`` instance for this model and service: + +.. code-block:: java + + var client = DynamicClient.builder() + .service(shapeId) + .model(model) + .protocol(new RestJsonClientProtocol(shapeId)) + .transport(new JavaHttpClientTransport()) + .endpointResolver(EndpointResolver.staticEndpoint("https://api.cafe.example.com")) + .build(); + +Now, create an input to call the service. Input is defined using a Document that mirrors what you'd see in the Smithy model. + +.. code-block:: java + + var input = Document.createFromObject(Map.of("coffeeType", "COLD_BREW")); + var result = client.call("CreateOrder", input).get(); + System.out.println(result); + +.. admonition:: Important + :class: note + + If an explicit protocol and transport are not provided to the builder, the builder will attempt to find protocol + and transport implementations on the classpath that match the protocol traits attached to the service. + + diff --git a/docs/source-2.0/java/client/generating-clients.rst b/docs/source-2.0/java/client/generating-clients.rst new file mode 100644 index 00000000000..66250f716f8 --- /dev/null +++ b/docs/source-2.0/java/client/generating-clients.rst @@ -0,0 +1,201 @@ +================== +Generating Clients +================== + +The Smithy Java :ref:`build plugin `, ``java-client-codegen``, generates Java clients from Smithy models, +and can be executed with both `Gradle `_ (recommended) or the :ref:`Smithy CLI `. + +.. admonition:: Important + :class: note + + The Smithy CLI is a prerequisite for this guide when using the ``smithy init``` commands. + See the :doc:`Smithy CLI installation guide <../../guides/smithy-cli/cli_installation>` + if you do not already have the CLI installed. + +----------------------------------- +Initial setup: Gradle (Recommended) +----------------------------------- + +To generated a Java client for a service, first create a new Smithy Gradle project. + +.. tip:: + + Use the ``smithy init``` CLI command to create a new Smithy project. + The command ``smithy init -t quickstart-gradle`` will create a new + basic Smithy Gradle project. + +Apply the `smithy-base`_ plugin to your Gradle build script to build your Smithy model +and execute build plugins. + +.. code-block:: diff + :caption: build.gradle.kts + + plugins { + `java-library` + + id("software.amazon.smithy.gradle.smithy-base") version "__smithy_gradle_version__" + } + +Add the following dependencies to your project: + + 1. Add the codegen `plugins`_ package as a ``smithyBuild`` dependency of your project. This makes the codegen plugins discoverable by the Smithy build task. + 2. Add the `client-core`_ package as a runtime dependency of your package. The ``client-core``` package is the only required dependency for all generated clients. + 3. Add any additional dependencies used by your client, such as protocols or auth schemes. + +.. code-block:: kotlin + :caption: build.gradle.kts + + dependencies { + // Add the code generation plugins to the smithy build classpath + smithyBuild("software.amazon.smithy.java.codegen:plugins:__smithy_java_version__") + + // Add the client-core dependency needed by the generated code + implementation("software.amazon.smithy.java:client-core:__smithy_java_version__") + + // Protocol implementations and auth schemes used by client + implementation("com.example:my-protocol:1.0.0") + implementation("com.example:my-auth-scheme:1.0.0") + } + +Now, define a service model in a ``model/`` directory at the root of your project. +The ``smithy-base``` Gradle plugin will automatically discover any models added to that directory. + +--------------------------- +Configuring code generation +--------------------------- + +In order to execute code generation, the ``java-client-codegen`` plugin must be added to +your :ref:`smithy-build ` config: + +.. code-block:: diff + :caption: smithy-build.json + + { + "version": "1.0", + "plugins": { + + "java-client-codegen": { + + "service": "com.example#CoffeeShop", // <- Replace with your service's ID + + // Generated Java code will use this as the root package namespace + + "namespace": "com.example.cafe" + + } + } + } + +---------------------------------------- +Add generated code to the Java sourceSet +---------------------------------------- + +Now the package is configured to generate client source code. +However, the generated client code must be added to a `sourceSet `_ +to be compiled by Gradle. To add the generated client code to the ``main`` sourceSet update your Gradle build script to +include the following: + +.. code-block:: kotlin + :caption: build.gradle.kts + + // Add generated Java sources to the main sourceSet so they are compiled alongside + // any other Java code in your package + afterEvaluate { + val clientPath = smithy.getPluginProjectionPath(smithy.sourceProjection.get(), "java-client-codegen") + sourceSets { + main { + java { + srcDir(clientPath) + } + } + } + } + + // Ensure client files are generated before java compilation is executed. + tasks.named("compileJava") { + dependsOn("smithyBuild") + } + +--------------- +Generating Code +--------------- + +To generate and compile your client code run a build from the root of your Gradle project: + +.. code-block:: sh + + ./gradlew clean build + +Building the project will generate code into the +``build/smithy-projections//source/java-client-codegen/`` directory. + +---------------- +Complete Example +---------------- + +The following Gradle build script, and ``smithy-build.json`` files provide a complete example of how to configure a +Gradle project to generate a Smithy Java client: + +.. code-block:: kotlin + :caption: build.gradle.kts + + plugins { + `java-library` + id("software.amazon.smithy.gradle.smithy-base") version "__smithy_gradle_version__" + } + + dependencies { + // Add the code generation plugin to the smithy build dependencies + smithyBuild("software.amazon.smithy.java.codegen:client:__smithy_java_version__") + + // Add any smithy model dependencies as `implementation` dependencies here. + // For example, you might add additional trait packages here. + implementation("...") + + // Add the client-core dependency needed by the generated code + implementation("software.amazon.smithy.java:client-core:__smithy_java_version__"") + + // Also add your protocol implementations or auth schemes as dependencies + implementation("com.example:my-protocol:1.0.0") + implementation("com.example:my-auth-scheme:1.0.0") + } + + // Add generated Java sources to the main sourceSet so they are compiled alongside + // any other java code in your package + afterEvaluate { + val clientPath = smithy.getPluginProjectionPath(smithy.sourceProjection.get(), "java-client-codegen") + sourceSets { + main { + java { + srcDir(clientPath) + } + } + } + } + + // Ensure client files are generated before java compilation is executed. + tasks.named("compileJava") { + dependsOn("smithyBuild") + } + + repositories { + mavenLocal() + mavenCentral() + } + +.. code-block:: json + :caption: smithy-build.json + + { + "version": "1.0", + "plugins": { + "java-client-codegen": { + "service": "com.example#CoffeeShop", + "namespace": "com.example.cafe", + // Default protocol for the client. Must have a corresponding trait in the + // model and implementation discoverable via SPI (see section on protocols below) + "protocol": "aws.protocols#restJson1", + // Adds a common header to all generated files + "headerFile": "license.txt" + } + } + } + + +.. _smithy-base: https://github.com/smithy-lang/smithy-gradle-plugin#smithy-base-plugin +.. _client-core: https://mvnrepository.com/artifact/software.amazon.smithy.java/client-core +.. _plugins: https://mvnrepository.com/artifact/software.amazon.smithy.java.codegen/plugins diff --git a/docs/source-2.0/java/client/index.rst b/docs/source-2.0/java/client/index.rst new file mode 100644 index 00000000000..44bfd637a01 --- /dev/null +++ b/docs/source-2.0/java/client/index.rst @@ -0,0 +1,24 @@ +================= +Client User Guide +================= + +This guide walks through how to use `Smithy Java `_ to generate Java clients from a Smithy model of a service. + +.. warning:: + + Smithy Java is currently in Developer Preview. All interfaces are subject to change. + +For a general overview of the Smithy IDL see the Smithy :doc:`../../quickstart` Guide + +For a general introduction the the Smithy Java framework see the Smithy :doc:`../quickstart` Guide. + +.. toctree:: + :maxdepth: 1 + + generating-clients + codegen-integrations + dynamic-client + configuration + customization + plugins + diff --git a/docs/source-2.0/java/client/plugins.rst b/docs/source-2.0/java/client/plugins.rst new file mode 100644 index 00000000000..e83752c7132 --- /dev/null +++ b/docs/source-2.0/java/client/plugins.rst @@ -0,0 +1,121 @@ +============== +Client Plugins +============== + +Smithy Java provides a number of built-in client plugins that add functionality to generated clients. + +---------- +MockPlugin +---------- + +The ``MockPlugin`` intercepts client requests and returns pre-defined mock responses, shapes, or exceptions. +The plugin facilitates testing client request/responses without the need to set up a Mock Server. + +Usage +^^^^^ + +Add the ``mock-client-plugin`` package as a dependency: + +.. code-block:: java + :caption: build.gradle.kts + + dependencies { + implementation("software.amazon.smithy.java.client.http.mock:mock-client-plugin:__smithy_java_version__") + } + +Use the plugin to return canned responses from the http client: + +.. code-block:: java + + // (1) Create a response queue and add a set of canned responses that will be returned + // from client in the order in which they were added to the queue. + var mockQueue = new MockQueue(); + mockQueue.enqueue( + HttpResponse.builder() + .statusCode(200) + .body(DataStream.ofString("{\"id\":\"1\"}")) + .build() + ); + mockQueue.enqueue( + HttpResponse.builder() + .statusCode(429) + .body(DataStream.ofString("{\"__type\":\"InvalidSprocketId\"}")) + .build() + ); + + // (2) Create a MockPlugin instance using the request queue created above. + var mockPlugin = MockPlugin.builder().addQueue(mockQueue).build(); + + // (3) Create a client instance that uses the MockPlugin. + var client = SprocketClient.builder() + .addPlugin(mockPlugin) + .build(); + + // (4) Call client to get the first canned response from the queue. + var response = client.createSprocket(CreateSprocketRequest.builder().id(2).build()); + + // (5) Inspect the HTTP requests that were sent to the client. + var requests = mock.getRequests(); + +--------------- +UserAgentPlugin +--------------- + +Adds a default ``User-Agent`` header to an HTTP request if none is set. + +.. note:: + + This plugin is applied by default by the ``HttpMessageExchange`` and any ``ClientTransport``‘s that use + the exchange. + +The added agent header has the form: + +.. code-block:: + + smithy-java/ ua/ os/# lang/java# m/ + +.. list-table:: + :header-rows: 1 + :widths: 20 10 70 + + * - Property + - Example + - Description + * - ``smithy`` + - ``0.0.1`` + - Smithy Java version in use by client in SemVer format. + * - ``ua`` + - ``2.1`` + - Version of the ``User-Agent`` metadata + * - ``os-family`` + - ``macos`` + - Operating system client is running on + * - ``version`` + - ``14.6.1`` + - version of OS or Language the client is running on. + * - ``features`` + - ``a,b`` + - Comma-separated list of feature Ids + +Feature IDs +^^^^^^^^^^^ + +Feature ID’s are set via the ``CallContext#FEATURE_IDS`` context key. +To add a new feature ID, update the FEATURE_IDS context key within an interceptor or in the client builder + +.. code-block:: java + + // (1) Get the existing feature ids + Set features = context.get(CallContext.FEATURE_IDS); + + // (2) Update with a new feature + features.add(new FeatureId() { + @Override + public String getShortName() { + return "short-name"; + } + }); + +A pair of ``app/{id}`` is added if ``CallContext#APPLICATION_ID`` is set, or a value is set in +the ``aws.userAgentAppId`` system property, or the value set in the ``AWS_SDK_UA_APP_ID`` environment variable. +See the `App ID `_ guide for more information. diff --git a/docs/source-2.0/java/index.rst b/docs/source-2.0/java/index.rst index daa88aff8d1..8b5bc501525 100644 --- a/docs/source-2.0/java/index.rst +++ b/docs/source-2.0/java/index.rst @@ -6,6 +6,7 @@ Java :maxdepth: 1 quickstart + client/index .. toctree:: :caption: References From ec51713a1854fe3dacd79153b23ab9b87af0e236 Mon Sep 17 00:00:00 2001 From: Hunter Mellema <124718352+hpmellema@users.noreply.github.com> Date: Fri, 14 Feb 2025 15:31:15 -0700 Subject: [PATCH 02/18] Apply suggestions from code review Co-authored-by: Hayden Baker --- docs/source-2.0/java/client/codegen-integrations.rst | 11 ++++------- docs/source-2.0/java/client/configuration.rst | 12 ++++++------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/docs/source-2.0/java/client/codegen-integrations.rst b/docs/source-2.0/java/client/codegen-integrations.rst index 5c50bec6ef8..403c85012a7 100644 --- a/docs/source-2.0/java/client/codegen-integrations.rst +++ b/docs/source-2.0/java/client/codegen-integrations.rst @@ -48,8 +48,7 @@ For example: errors: [NotFound] } -The waiter-codegen integration can be used to automatically generate waiters from waitable trait -definitions in your Smithy model. To add the integration to your project (using the Smithy Gradle plugins): +Using the waiters integration, you can automatically generate waiters from instances of the waitable trait in your Smithy model. If you are using the Smithy Gradle plugins, you can add this integration to your project like so: .. code-block:: kotlin :caption: build.gradle.kts @@ -63,12 +62,10 @@ definitions in your Smithy model. To add the integration to your project (using implementation("software.amazon.smithy.java:waiters:__smithy_java_version__") } -This will cause your client code generator to create a waiter container class call ``Waiters`` -in your generated client package. This container provides a method per waiter defined in your smithy model -that returns a pre-configured ``Waiter``` instance base on the configuration set in your Smithy model. +The code generator will create a class named ``Waiters`` in the client package. +This class provides a method per waiter defined in your smithy model. The methods return ``Waiter``` instances based on the configuration set in your Smithy model. -You can get an instance of this waiter container for a client by calling the ``waiters()`` method added -to clients by this integration. +To get an instance of a waiter, call the ``waiters()`` method on the client object: .. code-block:: java diff --git a/docs/source-2.0/java/client/configuration.rst b/docs/source-2.0/java/client/configuration.rst index 1949f14fc75..2dccde9f7dd 100644 --- a/docs/source-2.0/java/client/configuration.rst +++ b/docs/source-2.0/java/client/configuration.rst @@ -2,13 +2,13 @@ Configuring Clients =================== -Generated Smithy Java clients are composed of a number of runtime-configurable components: +Smithy Java clients are composed of several components which are configurable at runtime: * :ref:`Protocols ` - Defines how to serialize and deserialize a client request. * :ref:`Transports ` - Manages connections and the sending of data on the wire. -* :ref:`Auth Schemes ` - Add authentication/authorization information to a client request. +* :ref:`Auth Schemes ` - Adds authentication/authorization information to a client request. * :ref:`Endpoint Resolvers ` - Resolves the service endpoint to call. -* :ref:`Context Properties ` - Set typed properties on the client. +* :ref:`Context Properties ` - Sets typed properties on the client. .. _java-client-protocols: @@ -27,7 +27,7 @@ The Smithy IDL is protocol-agnostic and allows a service to support any number o (de)serialization of data. Like the Smithy IDL, Smithy Java clients are also protocol-agnostic and allow users to configure a protocol at runtime. -To set a protocol at runtime, add the protocol to the client builder as follows: +To set a protocol at runtime, add the protocol to the client builder: .. code-block:: java :caption: Set protocol at runtime @@ -44,9 +44,9 @@ To set a protocol at runtime, add the protocol to the client builder as follows Set a default protocol ^^^^^^^^^^^^^^^^^^^^^^ -While users may want to set a different protocol at runtime, it is typically desirable for generated clients to have a default protocol that can be used without any client configuration. +While users can set protocols at runtime, a default protocol should be set when generating the client: -To configure the client code generation plugin to set a default protocol, add the protocol’s fully qualified Smithy ID to the protocol setting in the smithy-build.json configuration file. +To configure the client plugin with a default protocol, add the protocol’s fully qualified Smithy ID to the protocol setting in the smithy-build.json configuration file: .. code-block:: json :caption: smithy-build.json From 8dc4b8ad166a22a46bdb7b782f46b44d8dd166fb Mon Sep 17 00:00:00 2001 From: Hunter Mellema <124718352+hpmellema@users.noreply.github.com> Date: Fri, 14 Feb 2025 15:50:39 -0700 Subject: [PATCH 03/18] Apply suggestions from code review Co-authored-by: Kevin Stich --- docs/source-2.0/java/client/customization.rst | 6 +++--- docs/source-2.0/java/client/dynamic-client.rst | 8 ++++---- docs/source-2.0/java/client/generating-clients.rst | 2 +- docs/source-2.0/java/client/index.rst | 4 ++-- docs/source-2.0/java/client/plugins.rst | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/source-2.0/java/client/customization.rst b/docs/source-2.0/java/client/customization.rst index ea9f026faf3..785daea00e5 100644 --- a/docs/source-2.0/java/client/customization.rst +++ b/docs/source-2.0/java/client/customization.rst @@ -18,7 +18,7 @@ Smithy Java supports client configuration overrides that are applied to a single var fooOutput = client.callFoo(fooInput, requestOverride); Each generated client will also generate a client-specific ``RequestOverride`` class that includes any custom -configuration settings. To get a client-specific override builder use the ``.requestOverrideBuilder`` on the +configuration settings. To get a client-specific override builder, use the ``.requestOverrideBuilder`` on the generated client: .. code-block:: java @@ -81,7 +81,7 @@ Plugins Plugins implement the ``ClientPlugin`` interface to modify client configuration when the client is created or when an operation is called (if added to a ``RequestOverrideConfig``). -Plugins set IdentityResolvers, EndpointResolvers, Interceptors, AuthSchemeResolvers, +Plugins set ``IdentityResolvers``, ``EndpointResolvers``, ``Interceptors``, ``AuthSchemeResolvers``, and other client configuration in a repeatable way. .. tip:: @@ -89,7 +89,7 @@ and other client configuration in a repeatable way. Create one or more common plugins for your organization to apply a standard configuration to generated clients. -To apply a plugins to a client at runtime use the addPlugin method on the client builder: +To apply a plugins to a client at runtime use the ``addPlugin`` method on the client builder: .. code-block:: java diff --git a/docs/source-2.0/java/client/dynamic-client.rst b/docs/source-2.0/java/client/dynamic-client.rst index 426ed984a7b..05fbd0fdc5b 100644 --- a/docs/source-2.0/java/client/dynamic-client.rst +++ b/docs/source-2.0/java/client/dynamic-client.rst @@ -2,11 +2,11 @@ Dynamic Client ============== -The dynamic client is used to interact with services more without a code-generated client. The dynamic client loads Smithy models at runtime, converting them to a schema-based client. Users can call a modeled service using document types as input and output. +The dynamic client is used to interact with services without a code-generated client. The dynamic client loads Smithy models at runtime, converting them to a schema-based client. Users can call a modeled service using document types as input and output. .. warning:: - The dynamic client currently does not currently support streaming or event streaming. + The dynamic client does not currently support streaming or event streaming. Usage ----- @@ -33,7 +33,7 @@ Then, load the Smithy model for use by the dynamic client. .assemble() .unwrap(); -Then, select the service to call, this should be a service shape in the loaded model, +Then, select the service to call. This should be a service shape in the loaded model, in this case a ``CoffeeShop`` service. .. code-block:: java @@ -52,7 +52,7 @@ Now, create the ``DynamicClient`` instance for this model and service: .endpointResolver(EndpointResolver.staticEndpoint("https://api.cafe.example.com")) .build(); -Now, create an input to call the service. Input is defined using a Document that mirrors what you'd see in the Smithy model. +Now, create an input to call the service. Input is defined using a ``Document`` that mirrors what you'd see in the Smithy model. .. code-block:: java diff --git a/docs/source-2.0/java/client/generating-clients.rst b/docs/source-2.0/java/client/generating-clients.rst index 66250f716f8..ffe10933d75 100644 --- a/docs/source-2.0/java/client/generating-clients.rst +++ b/docs/source-2.0/java/client/generating-clients.rst @@ -86,7 +86,7 @@ Add generated code to the Java sourceSet Now the package is configured to generate client source code. However, the generated client code must be added to a `sourceSet `_ -to be compiled by Gradle. To add the generated client code to the ``main`` sourceSet update your Gradle build script to +to be compiled by Gradle. To add the generated client code to the ``main`` sourceSet, update your Gradle build script to include the following: .. code-block:: kotlin diff --git a/docs/source-2.0/java/client/index.rst b/docs/source-2.0/java/client/index.rst index 44bfd637a01..47aa7ee898d 100644 --- a/docs/source-2.0/java/client/index.rst +++ b/docs/source-2.0/java/client/index.rst @@ -8,9 +8,9 @@ This guide walks through how to use `Smithy Java Date: Fri, 14 Feb 2025 15:51:10 -0700 Subject: [PATCH 04/18] Update docs/source-2.0/java/client/configuration.rst Co-authored-by: Hayden Baker --- docs/source-2.0/java/client/configuration.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/source-2.0/java/client/configuration.rst b/docs/source-2.0/java/client/configuration.rst index 2dccde9f7dd..1e3a57d05ff 100644 --- a/docs/source-2.0/java/client/configuration.rst +++ b/docs/source-2.0/java/client/configuration.rst @@ -70,8 +70,7 @@ For example to use the rpcv2 protocol with your service you would add the associ .. tip:: - The built-in rpcv2-cbor protocol is a generic binary protocol provided by Smithy Java that can be a - good choice for services that want a fast, compact data format. + The rpcv2-cbor protocol is a generic binary protocol and is good choice for services that want a fast, compact data format. Provided protocols ^^^^^^^^^^^^^^^^^^ From 39700ca647bb4a3693c06a5893191168daf76a5a Mon Sep 17 00:00:00 2001 From: Hunter Mellema <124718352+hpmellema@users.noreply.github.com> Date: Fri, 14 Feb 2025 15:55:49 -0700 Subject: [PATCH 05/18] Apply suggestions from code review Co-authored-by: Kevin Stich --- docs/source-2.0/java/client/configuration.rst | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/docs/source-2.0/java/client/configuration.rst b/docs/source-2.0/java/client/configuration.rst index 1e3a57d05ff..13b1d611d3d 100644 --- a/docs/source-2.0/java/client/configuration.rst +++ b/docs/source-2.0/java/client/configuration.rst @@ -60,7 +60,7 @@ To configure the client plugin with a default protocol, add the protocol’s ful } All protocols used for your service SHOULD use have an associated protocol trait applied to the service shape. -For example to use the rpcv2 protocol with your service you would add the associated protocol trait to your Smithy model: +For example to use the RPC v2 CBOR protocol with your service you would add the associated protocol trait to your Smithy model: .. code-block:: smithy :caption: model.smithy @@ -107,14 +107,14 @@ The Smithy Java framework provides the following pre-built protocols: - HTTP-based protocol that sends XML requests and responses - ``aws-client-restxml`` -Writing custom protocols +Writing custom protocols ^^^^^^^^^^^^^^^^^^^^^^^^^ To create a custom protocol, implement the ``ClientProtocol`` interface from the client-core package. .. tip:: - If you are writing a service that uses a custom HTTP protocol, you can extend the HttpClientProtocol + If you are writing a service that uses a custom HTTP protocol, you can extend the ``HttpClientProtocol`` and use one of the codecs provided by Smithy Java to get started. Default protocols are discovered via Service Provider Interface (SPI). To use a custom protocol as a default, you @@ -144,7 +144,7 @@ by modifying the client builder using the ``configureClient`` method. .. admonition:: Important :class: note - When overriding the configureClient method of a ClientTransport, you need to also call the configureClient + When overriding the ``configureClient`` method of a ``ClientTransport``, you need to also call the ``configureClient`` method of the ``MessageExchange``, if you want it to take effect. This allows for transports to override or even completely remove ``MessageExchange``-wide functionality. @@ -191,13 +191,13 @@ Provided transports Auth Schemes ------------ -Auth schemes add authentication/authorization information to a client request. The composition of Auth schemes includes: +Auth schemes add authentication/authorization information to a client request. The composition of auth schemes includes: 1. Scheme ID - A unique identifier for the authentication scheme that should correspond to the ID of a Smithy trait defining an auth scheme (see: https://smithy.io/2.0/spec/authentication-traits.html#smithy-api-authdefinition-trait) 2. Identity resolver - An API to acquire the customer's identity 3. Signer - An API to sign requests using the resolved identity. -Auth Schemes can be manually registered on a client at runtime or can be automatically registered by the client code generation plugin. To register an auth scheme at runtime: +Auth schemes can be manually registered on a client at runtime or can be automatically registered by the client code generation plugin. To register an auth scheme at runtime: .. code-block:: java @@ -208,15 +208,15 @@ Auth Schemes can be manually registered on a client at runtime or can be automat Automatic registration ^^^^^^^^^^^^^^^^^^^^^^ -The Client code generation plugin can discover Auth Schemes on the classpath. If a discovered auth scheme’s ID matches +The Client code generation plugin can discover auth schemes on the classpath. If a discovered auth scheme’s ID matches an auth scheme ID in the Smithy model it will be automatically registered in the generated client. -To add an auth scheme automatically to a generated client based on a trait in the model, the auth scheme must provided +To add an auth scheme automatically to a generated client based on a trait in the model, the auth scheme must provide an ``AuthSchemeFactory`` implementation and register that implementation via SPI. Smithy Java client codegen will automatically search the classpath for relevant ``AuthSchemeFactory``` implementations and attempt to match those with a corresponding trait in the model. -Effective Auth schemes +Effective auth schemes ^^^^^^^^^^^^^^^^^^^^^^ Operations may have one or more “effective auth schemes” that could be used to authenticate a request. @@ -259,18 +259,18 @@ See :ref:`Auth trait ` for a more thorough discussion on how auth sc Identity resolution ^^^^^^^^^^^^^^^^^^^ -To use an auth-scheme in a client, the client must register a corresponding identity resolver +To use an auth scheme in a client, the client must register a corresponding identity resolver that provides a compatible identity class. Auth schemes can provide a default resolver themselves or clients can register resolvers via the client builder or via a client plugin. .. tip:: - Multiple Identity resolvers can be chained together using the IdentityResolver.chain method. + Multiple identity resolvers can be chained together using the IdentityResolver.chain method. Provided Auth Schemes ^^^^^^^^^^^^^^^^^^^^^ -A number of auth schemes are provided by default in the client-http package. These include: +A number of auth schemes are provided by default in the ``client-http`` package. These include: * :ref:`httpBearerAuth ` - Supports HTTP Bearer Authentication as defined in RFC 6750. * :ref:`httpApiKeyAuth ` - Supports HTTP authentication using an API key sent in a header or query string parameter. @@ -283,10 +283,10 @@ Worked Example: Adding HTTP API Key Authentication Consider a Smithy modeled API for a service, ``ExampleService``. We would like to enable users of our generated SDK to authenticate to the API using an API key sent via an ``x-api-key`` HTTP header. -Smithy Java already provides an ``httpApiKeyAuth`` Auth Scheme that we can use to allow -this API Key authentication. +Smithy Java already provides an ``httpApiKeyAuth`` auth scheme that we can use to allow +this API key authentication. -Before we can add any Auth Scheme implementations to our generated client we must first add the associated +Before we can add any auth scheme implementations to our generated client we must first add the associated :ref:`@httpApiKeyAuth ` scheme trait to our service model. .. code-block:: smithy @@ -305,8 +305,8 @@ SHOULD always be modeled in your Smithy model using a trait. See the auth defini on how to define a custom auth scheme in your Smithy model. Now that we have added our auth trait to the Smithy model we need to add a corresponding AuthScheme implementation -to our client’s dependencies. The client-http package provides an ``HttpApiKeyAuthScheme`` implementation corresponding -to the @httpApiKeyAuth trait. +to our client’s dependencies. The ``client-http package`` provides an ``HttpApiKeyAuthScheme`` implementation corresponding +to the ``@httpApiKeyAuth`` trait. .. code-block:: kotlin :caption: build.gradle.kts @@ -329,7 +329,7 @@ For testing purposes we will provide a static resolver as follows: var client = ExampleService.builder() .addIdentityResolver( - IdentityResolver.of(new ApiKeyIdentity.create("example-api-key") + IdentityResolver.of(new ApiKeyIdentity.create("example-api-key")) ) .build() @@ -466,7 +466,7 @@ Composing Settings Some features require multiple custom settings. Because custom settings are simply Java interfaces, we can compose them. -For example, the SigV4 Auth scheme requires that a region setting and clock setting be set on a client as well +For example, the SigV4 auth scheme requires that a region setting and clock setting be set on a client as well as an additional settings, the signing name of the service. We can define the ``SigV4Settings`` interface as follows: .. code-block:: java From 911b44abdd37087723baf07d4dd58b1e4b6a1a58 Mon Sep 17 00:00:00 2001 From: Hunter Mellema Date: Fri, 14 Feb 2025 16:12:18 -0700 Subject: [PATCH 06/18] Update based on PR feedback --- .../java/client/codegen-integrations.rst | 18 +++++--- docs/source-2.0/java/client/configuration.rst | 46 ++++++++++--------- docs/source-2.0/java/client/customization.rst | 9 ++-- .../source-2.0/java/client/dynamic-client.rst | 7 ++- .../java/client/generating-clients.rst | 13 +++--- docs/source-2.0/java/client/index.rst | 3 +- 6 files changed, 57 insertions(+), 39 deletions(-) diff --git a/docs/source-2.0/java/client/codegen-integrations.rst b/docs/source-2.0/java/client/codegen-integrations.rst index 403c85012a7..d0f1e8e61cb 100644 --- a/docs/source-2.0/java/client/codegen-integrations.rst +++ b/docs/source-2.0/java/client/codegen-integrations.rst @@ -2,7 +2,8 @@ Codegen Integrations ==================== -Smithy Java provides a number of client codegen integrations that modify the code generated by the client codegen plugin. +Smithy Java provides a number of client codegen integrations that modify the code +generated by the client codegen plugin. -------------- Waiter Codegen @@ -12,9 +13,10 @@ Waiter Codegen Only synchronous waiters are supported at this time. -:ref:`Waiters ` are a client-side abstraction used to poll a resource until a desired state is reached, -or until it is determined that the resource will never enter a desirable end state. -Waiters can be defined in the Smithy model using the ``smithy.waiters#waitable`` trait. +:ref:`Waiters ` are a client-side abstraction used to poll a resource until a +desired state is reached, or until it is determined that the resource will never enter +a desirable end state. Waiters can be defined in the Smithy model using the +``smithy.waiters#waitable`` trait. For example: @@ -48,7 +50,9 @@ For example: errors: [NotFound] } -Using the waiters integration, you can automatically generate waiters from instances of the waitable trait in your Smithy model. If you are using the Smithy Gradle plugins, you can add this integration to your project like so: +Using the waiters integration, you can automatically generate waiters from instances +of the waitable trait in your Smithy model. If you are using the Smithy Gradle plugins, +you can add this integration to your project like so: .. code-block:: kotlin :caption: build.gradle.kts @@ -71,7 +75,9 @@ To get an instance of a waiter, call the ``waiters()`` method on the client obje // Get the generated waiter container var waiters = client.waiters(); + // Get the configurable waiter from the container var orderCompletedWaiter = waiters.orderCompleted(); + // Wait for up to 2 seconds for the waiter to complete. - orderCompletedWaiter.wait(input, Duration.ofSeconds(2); + orderCompletedWaiter.wait(input, Duration.ofSeconds(2)); diff --git a/docs/source-2.0/java/client/configuration.rst b/docs/source-2.0/java/client/configuration.rst index 13b1d611d3d..36fd5034d75 100644 --- a/docs/source-2.0/java/client/configuration.rst +++ b/docs/source-2.0/java/client/configuration.rst @@ -75,7 +75,7 @@ For example to use the RPC v2 CBOR protocol with your service you would add the Provided protocols ^^^^^^^^^^^^^^^^^^ -The Smithy Java framework provides the following pre-built protocols: +The Smithy Java framework provides the following protocols: .. list-table:: :header-rows: 1 @@ -89,22 +89,22 @@ The Smithy Java framework provides the following pre-built protocols: * - rpcv2Cbor - Smithy - ``smithy.protocols#rpcv2Cbor`` - - RPC-based protocol over HTTP that sends requests and responses with CBOR payloads. + - HTTP RPC protocol that sends requests and responses with CBOR payloads. - ``client-rpcv2-cbor`` * - AWS JSON 1.1 - AWS - ``aws.protocols#awsJson1_1`` - - HTTP protocol that sends "POST" requests and responses with JSON documents. + - HTTP protocol that sends "POST" requests and responses with JSON payloads. - ``aws-client-awsjson`` * - AWS Rest JSON 1.0 - AWS - ``aws.protocols#restJson1`` - - HTTP-based protocol that sends JSON requests and responses + - HTTP protocol that sends requests and responses with JSON payloads - ``aws-client-awsjson`` * - AWS Rest XML - AWS - ``aws.protocols#restXml`` - - HTTP-based protocol that sends XML requests and responses + - HTTP protocol that sends requests and responses with XML payloads. - ``aws-client-restxml`` Writing custom protocols @@ -123,12 +123,13 @@ Once you have defined your factory, add it’s fully qualified name to the servi (``META-INF/services/software.amazon.smithy.java.runtime.client.core.ClientProtocolFactory``). A default protocol must have a corresponding protocol trait applied to the service shape being generated. -Smithy Java codec‘s are used by both client and server protocols for generic (de)serialization of generated types into wire data such as JSON. -Protocols SHOULD use an appropriate codec for (de)serialization where possible. Smithy-Java provides XML, JSON, and CBOR codecs. +Smithy Java codec‘s are used by both client and server protocols for generic (de)serialization of generated types +into wire data such as JSON. Protocols SHOULD use an appropriate codec for (de)serialization where possible. +Smithy-Java provides XML, JSON, and CBOR codecs. When writing a custom protocol, we recommend writing compliance tests that can be used to validate the protocol across -multiple language implementations. The ``protocol-test-harness`` package provides a JUnit5 test harness for -running protocol compliance tests with Smithy Java. +multiple language implementations. The ``protocol-test-harness`` package provides a `JUnit5 `_ +test harness for running protocol compliance tests with Smithy Java. .. _java-client-transports: @@ -136,7 +137,7 @@ running protocol compliance tests with Smithy Java. Transports ---------- -Transports manages connections, and handle the sending/receiving of serialized requests/responses. +Transports manage connections, and handle the sending/receiving of serialized requests/responses. ``ClientTransport``'s can also configure default functionality like adding a user-agent header for HTTP request by modifying the client builder using the ``configureClient`` method. @@ -151,7 +152,7 @@ by modifying the client builder using the ``configureClient`` method. Transport Discovery ^^^^^^^^^^^^^^^^^^^ -Transport implementations can be automatically discovered by client code generators and dynamic clients via SPI. +Transport implementations can be discovered by client code generators and dynamic clients via SPI. To make a transport implementation discoverable, implement the ``ClientTransportFactory`` service provider. If no transport is set on a client, the client will attempt to resolve a transport compatible with the current protocol @@ -160,7 +161,7 @@ from the discoverable transport implementations. Setting a default transport ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -To set a default, add the following to your :ref:`smithy-build.json `: +To set a default transport, add the following to your :ref:`smithy-build.json `: .. code-block:: json :caption: smithy-build.json @@ -193,11 +194,13 @@ Auth Schemes Auth schemes add authentication/authorization information to a client request. The composition of auth schemes includes: -1. Scheme ID - A unique identifier for the authentication scheme that should correspond to the ID of a Smithy trait defining an auth scheme (see: https://smithy.io/2.0/spec/authentication-traits.html#smithy-api-authdefinition-trait) +1. Scheme ID - A unique identifier for the authentication scheme that should correspond to the ID of a Smithy trait +defining an auth scheme (see: https://smithy.io/2.0/spec/authentication-traits.html#smithy-api-authdefinition-trait) 2. Identity resolver - An API to acquire the customer's identity 3. Signer - An API to sign requests using the resolved identity. -Auth schemes can be manually registered on a client at runtime or can be automatically registered by the client code generation plugin. To register an auth scheme at runtime: +Auth schemes can be manually registered on a client at runtime or can be automatically registered by the client code +generation plugin. To register an auth scheme at runtime: .. code-block:: java @@ -272,9 +275,9 @@ Provided Auth Schemes A number of auth schemes are provided by default in the ``client-http`` package. These include: -* :ref:`httpBearerAuth ` - Supports HTTP Bearer Authentication as defined in RFC 6750. +* :ref:`httpBearerAuth ` - Supports HTTP Bearer authentication as defined in RFC 6750. * :ref:`httpApiKeyAuth ` - Supports HTTP authentication using an API key sent in a header or query string parameter. -* :ref:`httpBasicAuth ` - Indicates that a service supports HTTP Basic Authentication as defined in RFC 2617. +* :ref:`httpBasicAuth ` - Supports HTTP Basic authentication as defined in RFC 2617. Add the ``client-http`` package as a dependency of your project to make these auth schemes available in your service. @@ -301,8 +304,8 @@ Before we can add any auth scheme implementations to our generated client we mus } Authentication schemes are effectively part of your services interface and so (outside of testing) -SHOULD always be modeled in your Smithy model using a trait. See the auth definition trait for more information -on how to define a custom auth scheme in your Smithy model. +SHOULD always be modeled in your Smithy model using a trait. See the :ref:`@authDefinition ` + trait for more information on how to define a custom auth scheme in your Smithy model. Now that we have added our auth trait to the Smithy model we need to add a corresponding AuthScheme implementation to our client’s dependencies. The ``client-http package`` provides an ``HttpApiKeyAuthScheme`` implementation corresponding @@ -373,7 +376,7 @@ Endpoint Resolver ----------------- Endpoint resolvers determine the endpoint to use for an operation. For example, an endpoint resolver could - determine what subdomain to use, i.e. ``us-east-2.myservice.com`` based on a region setting on the client. +determine what subdomain to use, i.e. ``us-east-2.myservice.com`` based on a region setting on the client. To set a static endpoint for a client use the following client builder setter: @@ -426,7 +429,6 @@ For example we would write a custom setting as: Context.Key MY_PROPERTY = Context.key("A custom string configuration property"); default B custom(String custom) { - // ADD ANY VALIDATION OF THE VALUE HERE return putConfig(MY_PROPERTY, custom); } } @@ -501,5 +503,7 @@ When the ``SigV4Settings`` interface is added to the codegen configuration as a .. tip:: - Create a custom setting class for your organization that aggregates all common settings for your clients. This minimizes the number of code generation configurations you need to provide to create a functional client. Add new settings to the aggregate setting to add them to clients without changing the codegen configuration. + Create a custom setting class for your organization that aggregates all common settings for your clients. + This minimizes the number of code generation configurations you need to provide to create a functional client. + Add new settings to the aggregate setting to add them to clients without changing the codegen configuration. diff --git a/docs/source-2.0/java/client/customization.rst b/docs/source-2.0/java/client/customization.rst index 785daea00e5..ff51be1896f 100644 --- a/docs/source-2.0/java/client/customization.rst +++ b/docs/source-2.0/java/client/customization.rst @@ -5,7 +5,8 @@ Customizing Client Behavior Request-Level Overrides ----------------------- -Smithy Java supports client configuration overrides that are applied to a single request. Create and use an override as follows: +Smithy Java supports client configuration overrides that are applied to a single request. +Create and use an override as follows: .. code-block:: java @@ -50,7 +51,8 @@ The following hooks are supported: * **modifyBeforeDeserialization** - hook called before the response is deserialized * **readBeforeDeserialization** - called before the response is deserialized * **readAfterDeserialization** - called after the transport response message is deserialized -* **modifyBeforeAttemptCompletion** - hook called when an attempt is completed. This method can modify and return a new output or error matching the currently executing operation +* **modifyBeforeAttemptCompletion** - hook called when an attempt is completed. This method can + modify and return a new output or error matching the currently executing operation * **readAfterAttempt** - hook called when an attempt is completed * **modifyBeforeCompletion** - hook called when an execution is completed * **readAfterExecution** - called when an execution is completed @@ -100,7 +102,8 @@ To apply a plugins to a client at runtime use the ``addPlugin`` method on the cl .. admonition:: Important :class: note - Plugins are run only at client build time if added to the client builder or once before executing a call if they are included in a RequestOverrideConfig. + Plugins are run only at client build time if added to the client builder or once before executing a call if + they are included in a RequestOverrideConfig. Default Plugins ^^^^^^^^^^^^^^^ diff --git a/docs/source-2.0/java/client/dynamic-client.rst b/docs/source-2.0/java/client/dynamic-client.rst index 05fbd0fdc5b..8951b108bfe 100644 --- a/docs/source-2.0/java/client/dynamic-client.rst +++ b/docs/source-2.0/java/client/dynamic-client.rst @@ -2,7 +2,9 @@ Dynamic Client ============== -The dynamic client is used to interact with services without a code-generated client. The dynamic client loads Smithy models at runtime, converting them to a schema-based client. Users can call a modeled service using document types as input and output. +The dynamic client is used to interact with services without a code-generated client. +The dynamic client loads Smithy models at runtime, converting them to a schema-based client. +Users can call a modeled service using document types as input and output. .. warning:: @@ -52,7 +54,8 @@ Now, create the ``DynamicClient`` instance for this model and service: .endpointResolver(EndpointResolver.staticEndpoint("https://api.cafe.example.com")) .build(); -Now, create an input to call the service. Input is defined using a ``Document`` that mirrors what you'd see in the Smithy model. +Now, create an input to call the service. Input is defined using a ``Document`` that mirrors what you'd +see in the Smithy model. .. code-block:: java diff --git a/docs/source-2.0/java/client/generating-clients.rst b/docs/source-2.0/java/client/generating-clients.rst index ffe10933d75..122186874d6 100644 --- a/docs/source-2.0/java/client/generating-clients.rst +++ b/docs/source-2.0/java/client/generating-clients.rst @@ -37,8 +37,10 @@ and execute build plugins. Add the following dependencies to your project: - 1. Add the codegen `plugins`_ package as a ``smithyBuild`` dependency of your project. This makes the codegen plugins discoverable by the Smithy build task. - 2. Add the `client-core`_ package as a runtime dependency of your package. The ``client-core``` package is the only required dependency for all generated clients. + 1. Add the codegen `plugins`_ package as a ``smithyBuild`` dependency of your project. This makes the codegen + plugins discoverable by the Smithy build task. + 2. Add the `client-core`_ package as a runtime dependency of your package. + The ``client-core``` package is the only required dependency for all generated clients. 3. Add any additional dependencies used by your client, such as protocols or auth schemes. .. code-block:: kotlin @@ -84,10 +86,9 @@ your :ref:`smithy-build ` config: Add generated code to the Java sourceSet ---------------------------------------- -Now the package is configured to generate client source code. -However, the generated client code must be added to a `sourceSet `_ -to be compiled by Gradle. To add the generated client code to the ``main`` sourceSet, update your Gradle build script to -include the following: +Now the package is configured to generate client source code. However, the generated client code must be added to +a `sourceSet `_ to be compiled by Gradle. +To add the generated client code to the ``main`` sourceSet, update your Gradle build script to include the following: .. code-block:: kotlin :caption: build.gradle.kts diff --git a/docs/source-2.0/java/client/index.rst b/docs/source-2.0/java/client/index.rst index 47aa7ee898d..149990d4198 100644 --- a/docs/source-2.0/java/client/index.rst +++ b/docs/source-2.0/java/client/index.rst @@ -2,7 +2,8 @@ Client User Guide ================= -This guide walks through how to use `Smithy Java `_ to generate Java clients from a Smithy model of a service. +This guide walks through how to use `Smithy Java `_ to generate +Java clients from a Smithy model of a service. .. warning:: From 11d1ca06561858d100455936ba2786fa57b066b0 Mon Sep 17 00:00:00 2001 From: Hunter Mellema Date: Fri, 14 Feb 2025 16:19:05 -0700 Subject: [PATCH 07/18] Capitalization fixes --- .../java/client/codegen-integrations.rst | 4 ++-- docs/source-2.0/java/client/configuration.rst | 16 ++++++++-------- docs/source-2.0/java/client/customization.rst | 4 ++-- .../java/client/generating-clients.rst | 6 +++--- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/source-2.0/java/client/codegen-integrations.rst b/docs/source-2.0/java/client/codegen-integrations.rst index d0f1e8e61cb..20ce04d1187 100644 --- a/docs/source-2.0/java/client/codegen-integrations.rst +++ b/docs/source-2.0/java/client/codegen-integrations.rst @@ -6,7 +6,7 @@ Smithy Java provides a number of client codegen integrations that modify the cod generated by the client codegen plugin. -------------- -Waiter Codegen +Waiter codegen -------------- .. warning:: @@ -67,7 +67,7 @@ you can add this integration to your project like so: } The code generator will create a class named ``Waiters`` in the client package. -This class provides a method per waiter defined in your smithy model. The methods return ``Waiter``` instances based on the configuration set in your Smithy model. +This class provides a method per waiter defined in your Smithy model. The methods return ``Waiter``` instances based on the configuration set in your Smithy model. To get an instance of a waiter, call the ``waiters()`` method on the client object: diff --git a/docs/source-2.0/java/client/configuration.rst b/docs/source-2.0/java/client/configuration.rst index 36fd5034d75..10dba0766fd 100644 --- a/docs/source-2.0/java/client/configuration.rst +++ b/docs/source-2.0/java/client/configuration.rst @@ -125,7 +125,7 @@ A default protocol must have a corresponding protocol trait applied to the servi Smithy Java codec‘s are used by both client and server protocols for generic (de)serialization of generated types into wire data such as JSON. Protocols SHOULD use an appropriate codec for (de)serialization where possible. -Smithy-Java provides XML, JSON, and CBOR codecs. +Smithy Java provides XML, JSON, and CBOR codecs. When writing a custom protocol, we recommend writing compliance tests that can be used to validate the protocol across multiple language implementations. The ``protocol-test-harness`` package provides a `JUnit5 `_ @@ -149,7 +149,7 @@ by modifying the client builder using the ``configureClient`` method. method of the ``MessageExchange``, if you want it to take effect. This allows for transports to override or even completely remove ``MessageExchange``-wide functionality. -Transport Discovery +Transport discovery ^^^^^^^^^^^^^^^^^^^ Transport implementations can be discovered by client code generators and dynamic clients via SPI. @@ -270,7 +270,7 @@ or clients can register resolvers via the client builder or via a client plugin. Multiple identity resolvers can be chained together using the IdentityResolver.chain method. -Provided Auth Schemes +Provided auth schemes ^^^^^^^^^^^^^^^^^^^^^ A number of auth schemes are provided by default in the ``client-http`` package. These include: @@ -281,7 +281,7 @@ A number of auth schemes are provided by default in the ``client-http`` package. Add the ``client-http`` package as a dependency of your project to make these auth schemes available in your service. -Worked Example: Adding HTTP API Key Authentication +Worked example: Adding HTTP API key Authentication ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Consider a Smithy modeled API for a service, ``ExampleService``. We would like to enable users of our generated SDK @@ -372,7 +372,7 @@ Smithy Java also allows identity resolvers to be chained together if we want to .. _java-client-endpoints: ----------------- -Endpoint Resolver +Endpoint resolver ----------------- Endpoint resolvers determine the endpoint to use for an operation. For example, an endpoint resolver could @@ -393,7 +393,7 @@ To set a static endpoint for a client use the following client builder setter: .. _java-client-context: ------------------- -Context Properties +Context properties ------------------- Smithy Java clients allow users to add any configurations to a typed property bag, via the putConfig method. @@ -413,7 +413,7 @@ Configuration parameters can be set on a client using a typed property key via t .putContext(MY_PROPERTY, "value") .build(); -Custom Builder Setters +Custom builder setters ^^^^^^^^^^^^^^^^^^^^^^ For common settings on a client, it is often desirable to use specifically-named setter methods such as .region("us-east-1") @@ -463,7 +463,7 @@ Now we can use our new setting as follows: Default settings are typically paired with a default plugin to add the configuration and behavior of a feature (respectively) to a client by default. -Composing Settings +Composing settings ^^^^^^^^^^^^^^^^^^ Some features require multiple custom settings. Because custom settings are simply Java interfaces, we can compose them. diff --git a/docs/source-2.0/java/client/customization.rst b/docs/source-2.0/java/client/customization.rst index ff51be1896f..27a05796c98 100644 --- a/docs/source-2.0/java/client/customization.rst +++ b/docs/source-2.0/java/client/customization.rst @@ -2,7 +2,7 @@ Customizing Client Behavior =========================== -Request-Level Overrides +Request-level overrides ----------------------- Smithy Java supports client configuration overrides that are applied to a single request. @@ -105,7 +105,7 @@ To apply a plugins to a client at runtime use the ``addPlugin`` method on the cl Plugins are run only at client build time if added to the client builder or once before executing a call if they are included in a RequestOverrideConfig. -Default Plugins +Default plugins ^^^^^^^^^^^^^^^ Plugins can be applied by default at client instantiation. To apply a plugin by default , add the plugin’s diff --git a/docs/source-2.0/java/client/generating-clients.rst b/docs/source-2.0/java/client/generating-clients.rst index 122186874d6..653be0bf505 100644 --- a/docs/source-2.0/java/client/generating-clients.rst +++ b/docs/source-2.0/java/client/generating-clients.rst @@ -13,7 +13,7 @@ and can be executed with both `Gradle `_ (recommended) or t if you do not already have the CLI installed. ----------------------------------- -Initial setup: Gradle (Recommended) +Initial setup: Gradle (recommended) ----------------------------------- To generated a Java client for a service, first create a new Smithy Gradle project. @@ -112,7 +112,7 @@ To add the generated client code to the ``main`` sourceSet, update your Gradle b } --------------- -Generating Code +Generating code --------------- To generate and compile your client code run a build from the root of your Gradle project: @@ -125,7 +125,7 @@ Building the project will generate code into the ``build/smithy-projections//source/java-client-codegen/`` directory. ---------------- -Complete Example +Complete example ---------------- The following Gradle build script, and ``smithy-build.json`` files provide a complete example of how to configure a From d84cccd825294df4fe2523b604797af32b22274b Mon Sep 17 00:00:00 2001 From: Hunter Mellema Date: Fri, 14 Feb 2025 16:22:02 -0700 Subject: [PATCH 08/18] Additional updates based on feedback --- docs/source-2.0/java/client/configuration.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/source-2.0/java/client/configuration.rst b/docs/source-2.0/java/client/configuration.rst index 10dba0766fd..156df321ee2 100644 --- a/docs/source-2.0/java/client/configuration.rst +++ b/docs/source-2.0/java/client/configuration.rst @@ -59,8 +59,9 @@ To configure the client plugin with a default protocol, add the protocol’s ful } } -All protocols used for your service SHOULD use have an associated protocol trait applied to the service shape. -For example to use the RPC v2 CBOR protocol with your service you would add the associated protocol trait to your Smithy model: + +A service declares compatible protocols by applying the corresponding protocol trait on the service shape. +For example, if a service supports the rpcV2 protocol, it MUST have the protocol trait applied: .. code-block:: smithy :caption: model.smithy @@ -114,7 +115,7 @@ To create a custom protocol, implement the ``ClientProtocol`` interface from the .. tip:: - If you are writing a service that uses a custom HTTP protocol, you can extend the ``HttpClientProtocol`` + If you are writing a service that uses a custom HTTP protocol, you may extend the ``HttpClientProtocol`` and use one of the codecs provided by Smithy Java to get started. Default protocols are discovered via Service Provider Interface (SPI). To use a custom protocol as a default, you @@ -123,8 +124,8 @@ Once you have defined your factory, add it’s fully qualified name to the servi (``META-INF/services/software.amazon.smithy.java.runtime.client.core.ClientProtocolFactory``). A default protocol must have a corresponding protocol trait applied to the service shape being generated. -Smithy Java codec‘s are used by both client and server protocols for generic (de)serialization of generated types -into wire data such as JSON. Protocols SHOULD use an appropriate codec for (de)serialization where possible. +Codec‘s are used by client and server protocols for generic (de)serialization of types into wire data, such as JSON +Protocols SHOULD use an appropriate codec for (de)serialization where possible. Smithy Java provides XML, JSON, and CBOR codecs. When writing a custom protocol, we recommend writing compliance tests that can be used to validate the protocol across @@ -195,8 +196,8 @@ Auth Schemes Auth schemes add authentication/authorization information to a client request. The composition of auth schemes includes: 1. Scheme ID - A unique identifier for the authentication scheme that should correspond to the ID of a Smithy trait -defining an auth scheme (see: https://smithy.io/2.0/spec/authentication-traits.html#smithy-api-authdefinition-trait) -2. Identity resolver - An API to acquire the customer's identity +defining an auth scheme (see: https://smithy.io/2.0/spec/authentication-traits.html#smithy-api-authdefinition-trait). +2. Identity resolver - An API to acquire the customer's identity. 3. Signer - An API to sign requests using the resolved identity. Auth schemes can be manually registered on a client at runtime or can be automatically registered by the client code From 3c3f2e8c0de16d2c2dce992758aa75c7446b2221 Mon Sep 17 00:00:00 2001 From: Hunter Mellema <124718352+hpmellema@users.noreply.github.com> Date: Fri, 14 Feb 2025 16:24:49 -0700 Subject: [PATCH 09/18] Apply suggestions from code review Co-authored-by: Hayden Baker --- docs/source-2.0/java/client/configuration.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/source-2.0/java/client/configuration.rst b/docs/source-2.0/java/client/configuration.rst index 156df321ee2..7e11af037a6 100644 --- a/docs/source-2.0/java/client/configuration.rst +++ b/docs/source-2.0/java/client/configuration.rst @@ -118,17 +118,17 @@ To create a custom protocol, implement the ``ClientProtocol`` interface from the If you are writing a service that uses a custom HTTP protocol, you may extend the ``HttpClientProtocol`` and use one of the codecs provided by Smithy Java to get started. -Default protocols are discovered via Service Provider Interface (SPI). To use a custom protocol as a default, you +Protocols are discovered via Service Provider Interface (SPI). To use a custom protocol, you must implement a protocol factory that implements ``ClientProtocolFactory``. Once you have defined your factory, add it’s fully qualified name to the service provider file (``META-INF/services/software.amazon.smithy.java.runtime.client.core.ClientProtocolFactory``). -A default protocol must have a corresponding protocol trait applied to the service shape being generated. +As a reminder, make sure the custom protocol trait is applied to the service shape. Codec‘s are used by client and server protocols for generic (de)serialization of types into wire data, such as JSON Protocols SHOULD use an appropriate codec for (de)serialization where possible. Smithy Java provides XML, JSON, and CBOR codecs. -When writing a custom protocol, we recommend writing compliance tests that can be used to validate the protocol across +When writing a custom protocol, we recommend writing compliance tests, which are used to validate the protocol across multiple language implementations. The ``protocol-test-harness`` package provides a `JUnit5 `_ test harness for running protocol compliance tests with Smithy Java. @@ -177,7 +177,7 @@ To set a default transport, add the following to your :ref:`smithy-build.json Date: Fri, 14 Feb 2025 16:29:08 -0700 Subject: [PATCH 10/18] Even more fixes --- docs/source-2.0/java/client/configuration.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/source-2.0/java/client/configuration.rst b/docs/source-2.0/java/client/configuration.rst index 7e11af037a6..48005aab736 100644 --- a/docs/source-2.0/java/client/configuration.rst +++ b/docs/source-2.0/java/client/configuration.rst @@ -190,18 +190,18 @@ Provided transports .. _java-client-authSchemes: ------------ -Auth Schemes +Auth schemes ------------ -Auth schemes add authentication/authorization information to a client request. The composition of auth schemes includes: +Auth schemes add authentication/authorization information to a client request. An auth scheme is composed of: -1. Scheme ID - A unique identifier for the authentication scheme that should correspond to the ID of a Smithy trait +1. Scheme ID - A unique identifier for the auth scheme. It SHOULD correspond to the ID of a Smithy trait defining an auth scheme (see: https://smithy.io/2.0/spec/authentication-traits.html#smithy-api-authdefinition-trait). 2. Identity resolver - An API to acquire the customer's identity. 3. Signer - An API to sign requests using the resolved identity. -Auth schemes can be manually registered on a client at runtime or can be automatically registered by the client code -generation plugin. To register an auth scheme at runtime: +Auth Schemes may be registered by the client at runtime. To register an auth scheme, +use the ``putSupportedAuthSchemes`` method: .. code-block:: java @@ -258,7 +258,7 @@ overriding any auth trait specified on a service. operation OperationB {} https://smithy.io/2.0/spec/authentication-traits.html#smithy-api-auth-trait -See :ref:`Auth trait ` for a more thorough discussion on how auth schemes are resolved. +See :ref:`@auth ` trait for a more thorough discussion on how auth schemes are resolved. Identity resolution ^^^^^^^^^^^^^^^^^^^ @@ -282,7 +282,7 @@ A number of auth schemes are provided by default in the ``client-http`` package. Add the ``client-http`` package as a dependency of your project to make these auth schemes available in your service. -Worked example: Adding HTTP API key Authentication +Worked example: Adding HTTP API key authentication ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Consider a Smithy modeled API for a service, ``ExampleService``. We would like to enable users of our generated SDK @@ -308,7 +308,7 @@ Authentication schemes are effectively part of your services interface and so (o SHOULD always be modeled in your Smithy model using a trait. See the :ref:`@authDefinition ` trait for more information on how to define a custom auth scheme in your Smithy model. -Now that we have added our auth trait to the Smithy model we need to add a corresponding AuthScheme implementation +Now that we have added our auth trait to the Smithy model we need to add a corresponding auth scheme implementation to our client’s dependencies. The ``client-http package`` provides an ``HttpApiKeyAuthScheme`` implementation corresponding to the ``@httpApiKeyAuth`` trait. From ebbe788d3bc867a60e6f86ef0bf6e929ff15c9d8 Mon Sep 17 00:00:00 2001 From: Hunter Mellema Date: Fri, 14 Feb 2025 16:32:47 -0700 Subject: [PATCH 11/18] Fix bad indent --- docs/source-2.0/java/client/configuration.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source-2.0/java/client/configuration.rst b/docs/source-2.0/java/client/configuration.rst index 48005aab736..e89d23057c2 100644 --- a/docs/source-2.0/java/client/configuration.rst +++ b/docs/source-2.0/java/client/configuration.rst @@ -306,7 +306,7 @@ Before we can add any auth scheme implementations to our generated client we mus Authentication schemes are effectively part of your services interface and so (outside of testing) SHOULD always be modeled in your Smithy model using a trait. See the :ref:`@authDefinition ` - trait for more information on how to define a custom auth scheme in your Smithy model. +trait for more information on how to define a custom auth scheme in your Smithy model. Now that we have added our auth trait to the Smithy model we need to add a corresponding auth scheme implementation to our client’s dependencies. The ``client-http package`` provides an ``HttpApiKeyAuthScheme`` implementation corresponding From af5dabe40c749550fcf499592d93e370b18cc114 Mon Sep 17 00:00:00 2001 From: Hunter Mellema <124718352+hpmellema@users.noreply.github.com> Date: Wed, 19 Feb 2025 08:20:56 -0700 Subject: [PATCH 12/18] Apply suggestions from code review Co-authored-by: Hayden Baker --- docs/source-2.0/java/client/configuration.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/source-2.0/java/client/configuration.rst b/docs/source-2.0/java/client/configuration.rst index e89d23057c2..f5bdc33dd18 100644 --- a/docs/source-2.0/java/client/configuration.rst +++ b/docs/source-2.0/java/client/configuration.rst @@ -469,8 +469,7 @@ Composing settings Some features require multiple custom settings. Because custom settings are simply Java interfaces, we can compose them. -For example, the SigV4 auth scheme requires that a region setting and clock setting be set on a client as well -as an additional settings, the signing name of the service. We can define the ``SigV4Settings`` interface as follows: +For example, the SigV4 auth scheme requires that region, clock, and signing name settings be configured on a client. We can define the ``SigV4Settings`` interface as follows: .. code-block:: java :caption: composed setting @@ -499,8 +498,8 @@ as an additional settings, the signing name of the service. We can define the `` } } -When the ``SigV4Settings`` interface is added to the codegen configuration as a default setting it will also add the -``ClockSetting`` and ``RegionSetting`` setters to the generated client’s builder. +When the ``SigV4Settings`` interface is added to the codegen configuration as a default setting, the +``ClockSetting`` and ``RegionSetting`` setters will be included in the generated client’s builder. .. tip:: From 9c958552ca51a55998932babf758d1e2f47b47d5 Mon Sep 17 00:00:00 2001 From: Hunter Mellema <124718352+hpmellema@users.noreply.github.com> Date: Wed, 19 Feb 2025 08:22:07 -0700 Subject: [PATCH 13/18] Apply suggestions from code review Co-authored-by: Hayden Baker --- docs/source-2.0/java/client/customization.rst | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/docs/source-2.0/java/client/customization.rst b/docs/source-2.0/java/client/customization.rst index 27a05796c98..71afa71b9fa 100644 --- a/docs/source-2.0/java/client/customization.rst +++ b/docs/source-2.0/java/client/customization.rst @@ -18,7 +18,7 @@ Create and use an override as follows: var fooOutput = client.callFoo(fooInput, requestOverride); -Each generated client will also generate a client-specific ``RequestOverride`` class that includes any custom +Each generated client will contain a client-specific ``RequestOverride`` class that includes any custom configuration settings. To get a client-specific override builder, use the ``.requestOverrideBuilder`` on the generated client: @@ -48,13 +48,13 @@ The following hooks are supported: * **modifyBeforeTransmit** - called before the transport request message is sent to the service * **readBeforeTransmit** - called before the transport request message is sent to the * service * **readAfterTransmit** - called after the transport request message is sent to the service and a transport response message is received -* **modifyBeforeDeserialization** - hook called before the response is deserialized +* **modifyBeforeDeserialization** - called before the response is deserialized * **readBeforeDeserialization** - called before the response is deserialized * **readAfterDeserialization** - called after the transport response message is deserialized * **modifyBeforeAttemptCompletion** - hook called when an attempt is completed. This method can modify and return a new output or error matching the currently executing operation -* **readAfterAttempt** - hook called when an attempt is completed -* **modifyBeforeCompletion** - hook called when an execution is completed +* **readAfterAttempt** - called when an attempt is completed +* **modifyBeforeCompletion** - called when an execution is completed * **readAfterExecution** - called when an execution is completed Interceptors implement the ``ClientInterceptor`` interface and override one or more hook methods. @@ -83,7 +83,7 @@ Plugins Plugins implement the ``ClientPlugin`` interface to modify client configuration when the client is created or when an operation is called (if added to a ``RequestOverrideConfig``). -Plugins set ``IdentityResolvers``, ``EndpointResolvers``, ``Interceptors``, ``AuthSchemeResolvers``, +Plugins may set ``IdentityResolvers``, ``EndpointResolvers``, ``Interceptors``, ``AuthSchemeResolvers``, and other client configuration in a repeatable way. .. tip:: @@ -91,7 +91,7 @@ and other client configuration in a repeatable way. Create one or more common plugins for your organization to apply a standard configuration to generated clients. -To apply a plugins to a client at runtime use the ``addPlugin`` method on the client builder: +To apply a plugins to a client at runtime, use the ``addPlugin`` method on the client builder: .. code-block:: java @@ -102,13 +102,13 @@ To apply a plugins to a client at runtime use the ``addPlugin`` method on the cl .. admonition:: Important :class: note - Plugins are run only at client build time if added to the client builder or once before executing a call if - they are included in a RequestOverrideConfig. + Plugins are run once at client build time if added to the client builder, or each time a request is made if + added through a ``RequestOverrideConfig``. Default plugins ^^^^^^^^^^^^^^^ -Plugins can be applied by default at client instantiation. To apply a plugin by default , add the plugin’s +Plugins can be applied by default at client instantiation. To apply a plugin by default, add the plugin’s fully qualified name to the ``defaultPlugins``` setting to your :ref`smithy-build ` configuration: .. code-block:: json @@ -124,7 +124,6 @@ fully qualified name to the ``defaultPlugins``` setting to your :ref`smithy-buil .. admonition:: Important :class: note - Because default plugins need to be instantiated with no user input they must have a public, - zero-arg constructor defined. The code generator will check for an empty constructor when - resolving default plugins and fail if none is found. + Plugins must have a public, zero-arg constructor defined. The code generator will check for an + empty constructor when resolving default plugins and fail if one is not found. From 091ca6d73b148ba2cdf536181b4dcc57bd4b369f Mon Sep 17 00:00:00 2001 From: Hunter Mellema <124718352+hpmellema@users.noreply.github.com> Date: Wed, 19 Feb 2025 08:24:23 -0700 Subject: [PATCH 14/18] Apply suggestions from code review Co-authored-by: Hayden Baker --- docs/source-2.0/java/client/customization.rst | 2 +- .../source-2.0/java/client/dynamic-client.rst | 9 ++++---- .../java/client/generating-clients.rst | 21 ++++++++++--------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/source-2.0/java/client/customization.rst b/docs/source-2.0/java/client/customization.rst index 71afa71b9fa..4be6048a780 100644 --- a/docs/source-2.0/java/client/customization.rst +++ b/docs/source-2.0/java/client/customization.rst @@ -51,7 +51,7 @@ The following hooks are supported: * **modifyBeforeDeserialization** - called before the response is deserialized * **readBeforeDeserialization** - called before the response is deserialized * **readAfterDeserialization** - called after the transport response message is deserialized -* **modifyBeforeAttemptCompletion** - hook called when an attempt is completed. This method can +* **modifyBeforeAttemptCompletion** - called when an attempt is completed. This method can modify and return a new output or error matching the currently executing operation * **readAfterAttempt** - called when an attempt is completed * **modifyBeforeCompletion** - called when an execution is completed diff --git a/docs/source-2.0/java/client/dynamic-client.rst b/docs/source-2.0/java/client/dynamic-client.rst index 8951b108bfe..eae4bf8ea12 100644 --- a/docs/source-2.0/java/client/dynamic-client.rst +++ b/docs/source-2.0/java/client/dynamic-client.rst @@ -22,7 +22,7 @@ Add the dynamic-client module as a dependency of your project: implementation("software.amazon.smithy.java:dynamicclient:__smithy_java_version__") } -Then, load the Smithy model for use by the dynamic client. +Then, load a Smithy model: .. code-block:: java @@ -35,8 +35,7 @@ Then, load the Smithy model for use by the dynamic client. .assemble() .unwrap(); -Then, select the service to call. This should be a service shape in the loaded model, -in this case a ``CoffeeShop`` service. +Then, select a service shape in the loaded model to call. In this case, the ``CoffeeShop`` service: .. code-block:: java @@ -54,8 +53,8 @@ Now, create the ``DynamicClient`` instance for this model and service: .endpointResolver(EndpointResolver.staticEndpoint("https://api.cafe.example.com")) .build(); -Now, create an input to call the service. Input is defined using a ``Document`` that mirrors what you'd -see in the Smithy model. +To call the service, create an input using a ``Document`` that mirrors what's defined in the Smithy model. +The ``Document.createFromObject`` method can create a ``Document`` from a map: .. code-block:: java diff --git a/docs/source-2.0/java/client/generating-clients.rst b/docs/source-2.0/java/client/generating-clients.rst index 653be0bf505..82af488d7cc 100644 --- a/docs/source-2.0/java/client/generating-clients.rst +++ b/docs/source-2.0/java/client/generating-clients.rst @@ -3,12 +3,12 @@ Generating Clients ================== The Smithy Java :ref:`build plugin `, ``java-client-codegen``, generates Java clients from Smithy models, -and can be executed with both `Gradle `_ (recommended) or the :ref:`Smithy CLI `. +and can be executed with `Gradle `_ (recommended) or the :ref:`Smithy CLI `. .. admonition:: Important :class: note - The Smithy CLI is a prerequisite for this guide when using the ``smithy init``` commands. + The Smithy CLI is a prerequisite for this guide. See the :doc:`Smithy CLI installation guide <../../guides/smithy-cli/cli_installation>` if you do not already have the CLI installed. @@ -16,7 +16,7 @@ and can be executed with both `Gradle `_ (recommended) or t Initial setup: Gradle (recommended) ----------------------------------- -To generated a Java client for a service, first create a new Smithy Gradle project. +To generate a Java client for a service, start by creating a new Smithy Gradle project: .. tip:: @@ -25,7 +25,7 @@ To generated a Java client for a service, first create a new Smithy Gradle proje basic Smithy Gradle project. Apply the `smithy-base`_ plugin to your Gradle build script to build your Smithy model -and execute build plugins. +and execute build plugins: .. code-block:: diff :caption: build.gradle.kts @@ -86,9 +86,10 @@ your :ref:`smithy-build ` config: Add generated code to the Java sourceSet ---------------------------------------- -Now the package is configured to generate client source code. However, the generated client code must be added to -a `sourceSet `_ to be compiled by Gradle. -To add the generated client code to the ``main`` sourceSet, update your Gradle build script to include the following: +Your package is now configured to generate Java client source code. However, the generated code must be +added to a `sourceSet `_ to be +compiled by Gradle. To add the generated code to the ``main`` sourceSet, add the following to your +Gradle build script: .. code-block:: kotlin :caption: build.gradle.kts @@ -115,20 +116,20 @@ To add the generated client code to the ``main`` sourceSet, update your Gradle b Generating code --------------- -To generate and compile your client code run a build from the root of your Gradle project: +To generate and compile your client code, run a build from the root of your Gradle project: .. code-block:: sh ./gradlew clean build -Building the project will generate code into the +Building the project will generate code in the ``build/smithy-projections//source/java-client-codegen/`` directory. ---------------- Complete example ---------------- -The following Gradle build script, and ``smithy-build.json`` files provide a complete example of how to configure a +The following Gradle build script and ``smithy-build.json`` files provide a complete example of how to configure a Gradle project to generate a Smithy Java client: .. code-block:: kotlin From f6b76c8c41c7eddfc1474ef465cdf993c53610c1 Mon Sep 17 00:00:00 2001 From: Hunter Mellema <124718352+hpmellema@users.noreply.github.com> Date: Wed, 19 Feb 2025 08:26:46 -0700 Subject: [PATCH 15/18] Apply suggestions from code review Co-authored-by: Hayden Baker --- docs/source-2.0/java/client/plugins.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source-2.0/java/client/plugins.rst b/docs/source-2.0/java/client/plugins.rst index 459c66fec74..ebd36cbc324 100644 --- a/docs/source-2.0/java/client/plugins.rst +++ b/docs/source-2.0/java/client/plugins.rst @@ -2,7 +2,7 @@ Client Plugins ============== -Smithy Java provides a number of built-in client plugins that add functionality to generated clients. +Smithy Java provides a number of client plugins that add functionality to generated clients. ---------- MockPlugin @@ -61,7 +61,7 @@ Use the plugin to return canned responses from the http client: UserAgentPlugin --------------- -Adds a default ``User-Agent`` header to an HTTP request if none is set. +The ``UserAgentPlugin``adds a default ``User-Agent`` header to an HTTP request if none is set. .. note:: From fab1a33a94e26b02da82559fb5f7ae98620dbc44 Mon Sep 17 00:00:00 2001 From: Hunter Mellema <124718352+hpmellema@users.noreply.github.com> Date: Wed, 19 Feb 2025 08:46:23 -0700 Subject: [PATCH 16/18] Apply suggestions from code review --- .../java/client/codegen-integrations.rst | 2 +- docs/source-2.0/java/client/configuration.rst | 16 ++++++++-------- docs/source-2.0/java/client/customization.rst | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/source-2.0/java/client/codegen-integrations.rst b/docs/source-2.0/java/client/codegen-integrations.rst index 20ce04d1187..ddd7e0bf94e 100644 --- a/docs/source-2.0/java/client/codegen-integrations.rst +++ b/docs/source-2.0/java/client/codegen-integrations.rst @@ -51,7 +51,7 @@ For example: } Using the waiters integration, you can automatically generate waiters from instances -of the waitable trait in your Smithy model. If you are using the Smithy Gradle plugins, +of the ``waitable`` trait in your Smithy model. If you are using the Smithy Gradle plugins, you can add this integration to your project like so: .. code-block:: kotlin diff --git a/docs/source-2.0/java/client/configuration.rst b/docs/source-2.0/java/client/configuration.rst index f5bdc33dd18..d6bc2d20133 100644 --- a/docs/source-2.0/java/client/configuration.rst +++ b/docs/source-2.0/java/client/configuration.rst @@ -44,7 +44,7 @@ To set a protocol at runtime, add the protocol to the client builder: Set a default protocol ^^^^^^^^^^^^^^^^^^^^^^ -While users can set protocols at runtime, a default protocol should be set when generating the client: +While users can set protocols at runtime, a default protocol should be set when generating the client. To configure the client plugin with a default protocol, add the protocol’s fully qualified Smithy ID to the protocol setting in the smithy-build.json configuration file: @@ -111,7 +111,7 @@ The Smithy Java framework provides the following protocols: Writing custom protocols ^^^^^^^^^^^^^^^^^^^^^^^^^ -To create a custom protocol, implement the ``ClientProtocol`` interface from the client-core package. +To create a custom protocol, implement the ``ClientProtocol`` interface from the ``client-core`` package. .. tip:: @@ -140,7 +140,7 @@ Transports Transports manage connections, and handle the sending/receiving of serialized requests/responses. -``ClientTransport``'s can also configure default functionality like adding a user-agent header for HTTP request +``ClientTransport``'s can also configure default functionality like adding a user-agent header for an HTTP request by modifying the client builder using the ``configureClient`` method. .. admonition:: Important @@ -269,7 +269,7 @@ or clients can register resolvers via the client builder or via a client plugin. .. tip:: - Multiple identity resolvers can be chained together using the IdentityResolver.chain method. + Multiple identity resolvers can be chained together using the ``IdentityResolver.chain`` method. Provided auth schemes ^^^^^^^^^^^^^^^^^^^^^ @@ -291,7 +291,7 @@ Smithy Java already provides an ``httpApiKeyAuth`` auth scheme that we can use t this API key authentication. Before we can add any auth scheme implementations to our generated client we must first add the associated -:ref:`@httpApiKeyAuth ` scheme trait to our service model. +:ref:`@httpApiKeyAuth ` scheme trait to our service model: .. code-block:: smithy :caption: model.smithy @@ -310,7 +310,7 @@ trait for more information on how to define a custom auth scheme in your Smithy Now that we have added our auth trait to the Smithy model we need to add a corresponding auth scheme implementation to our client’s dependencies. The ``client-http package`` provides an ``HttpApiKeyAuthScheme`` implementation corresponding -to the ``@httpApiKeyAuth`` trait. +to the ``@httpApiKeyAuth`` trait: .. code-block:: kotlin :caption: build.gradle.kts @@ -363,7 +363,7 @@ Or, we could create a custom resolver that resolves the ``ApiKeyIdentity`` from return CompletableFuture.completedFuture(IdentityResult.of(ApiKeyIdentity.create(apiKey))); } -Smithy Java also allows identity resolvers to be chained together if we want to check multiple locations for the client. +Smithy Java also allows identity resolvers to be chained together if we want to check multiple locations for the client: .. code-block:: java :caption: Chaining identity resolvers @@ -417,7 +417,7 @@ Configuration parameters can be set on a client using a typed property key via t Custom builder setters ^^^^^^^^^^^^^^^^^^^^^^ -For common settings on a client, it is often desirable to use specifically-named setter methods such as .region("us-east-1") +For common settings on a client, it is often desirable to use specifically-named setter methods such as ``.region("us-east-1")`` rather than requiring users to know the specific context property to use for a configuration parameter. The ``ClientSetting`` interface can be used to create a custom setter that for client builders. diff --git a/docs/source-2.0/java/client/customization.rst b/docs/source-2.0/java/client/customization.rst index 4be6048a780..6aaa1155f88 100644 --- a/docs/source-2.0/java/client/customization.rst +++ b/docs/source-2.0/java/client/customization.rst @@ -19,7 +19,7 @@ Create and use an override as follows: var fooOutput = client.callFoo(fooInput, requestOverride); Each generated client will contain a client-specific ``RequestOverride`` class that includes any custom -configuration settings. To get a client-specific override builder, use the ``.requestOverrideBuilder`` on the +configuration settings. To get a client-specific override builder, use the ``.requestOverrideBuilder`` method on the generated client: .. code-block:: java From 34a560f65e88c98934c9eb131a68e9374b1f32d8 Mon Sep 17 00:00:00 2001 From: Hunter Mellema Date: Wed, 19 Feb 2025 09:02:07 -0700 Subject: [PATCH 17/18] Address PR feedback --- docs/source-2.0/java/client/configuration.rst | 11 ++++----- .../source-2.0/java/client/dynamic-client.rst | 14 +++++------ .../java/client/generating-clients.rst | 23 +++++++++++++++---- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/docs/source-2.0/java/client/configuration.rst b/docs/source-2.0/java/client/configuration.rst index d6bc2d20133..b9ff5c7a1e8 100644 --- a/docs/source-2.0/java/client/configuration.rst +++ b/docs/source-2.0/java/client/configuration.rst @@ -212,13 +212,10 @@ use the ``putSupportedAuthSchemes`` method: Automatic registration ^^^^^^^^^^^^^^^^^^^^^^ -The Client code generation plugin can discover auth schemes on the classpath. If a discovered auth scheme’s ID matches -an auth scheme ID in the Smithy model it will be automatically registered in the generated client. - -To add an auth scheme automatically to a generated client based on a trait in the model, the auth scheme must provide -an ``AuthSchemeFactory`` implementation and register that implementation via SPI. Smithy Java client codegen will -automatically search the classpath for relevant ``AuthSchemeFactory``` implementations and attempt to match those with -a corresponding trait in the model. +The Client code generation plugin can discover auth schemes on the classpath. To be discoverable, the auth scheme +must provide an ``AuthSchemeFactory`` implementation and register that implementation via SPI. Smithy Java client +codegen plugin will automatically search the classpath for relevant ``AuthSchemeFactory``` implementations and attempt +to match those with a corresponding trait in the model. Effective auth schemes ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/source-2.0/java/client/dynamic-client.rst b/docs/source-2.0/java/client/dynamic-client.rst index eae4bf8ea12..0346dd15958 100644 --- a/docs/source-2.0/java/client/dynamic-client.rst +++ b/docs/source-2.0/java/client/dynamic-client.rst @@ -53,6 +53,12 @@ Now, create the ``DynamicClient`` instance for this model and service: .endpointResolver(EndpointResolver.staticEndpoint("https://api.cafe.example.com")) .build(); +.. admonition:: Important + :class: note + + If an explicit protocol and transport are not provided to the builder, the builder will attempt to find protocol + and transport implementations on the classpath that match the protocol traits attached to the service. + To call the service, create an input using a ``Document`` that mirrors what's defined in the Smithy model. The ``Document.createFromObject`` method can create a ``Document`` from a map: @@ -61,11 +67,3 @@ The ``Document.createFromObject`` method can create a ``Document`` from a map: var input = Document.createFromObject(Map.of("coffeeType", "COLD_BREW")); var result = client.call("CreateOrder", input).get(); System.out.println(result); - -.. admonition:: Important - :class: note - - If an explicit protocol and transport are not provided to the builder, the builder will attempt to find protocol - and transport implementations on the classpath that match the protocol traits attached to the service. - - diff --git a/docs/source-2.0/java/client/generating-clients.rst b/docs/source-2.0/java/client/generating-clients.rst index 82af488d7cc..cdd37047e23 100644 --- a/docs/source-2.0/java/client/generating-clients.rst +++ b/docs/source-2.0/java/client/generating-clients.rst @@ -16,13 +16,26 @@ and can be executed with `Gradle `_ (recommended) or the :r Initial setup: Gradle (recommended) ----------------------------------- -To generate a Java client for a service, start by creating a new Smithy Gradle project: +To generate a Java client for a service, start by creating a new Smithy Gradle project. -.. tip:: +The ``smithy init``` CLI command can be used to create a new Smithy Gradle project: - Use the ``smithy init``` CLI command to create a new Smithy project. - The command ``smithy init -t quickstart-gradle`` will create a new - basic Smithy Gradle project. +.. code-block:: sh + + smithy init -t quickstart-gradle + +A Smithy Gradle project should contain a Gradle settings file, a Gradle build script, +a :ref:`smithy-build.json ` configuration file, and a `model/` directory +containing Smithy models. For example: + +.. code-block:: sh + + my-project/ + ├── model/ + │ ├── ... + ├── smithy-build.json + ├── build.gradle.kts + └── settings.gradle Apply the `smithy-base`_ plugin to your Gradle build script to build your Smithy model and execute build plugins: From eae43e3e67aa054e71228106742c014a01a4bc67 Mon Sep 17 00:00:00 2001 From: Hunter Mellema Date: Wed, 19 Feb 2025 09:06:30 -0700 Subject: [PATCH 18/18] Remove reference to exchanges --- docs/source-2.0/java/client/plugins.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/source-2.0/java/client/plugins.rst b/docs/source-2.0/java/client/plugins.rst index ebd36cbc324..0456f14e8bd 100644 --- a/docs/source-2.0/java/client/plugins.rst +++ b/docs/source-2.0/java/client/plugins.rst @@ -65,8 +65,7 @@ The ``UserAgentPlugin``adds a default ``User-Agent`` header to an HTTP request i .. note:: - This plugin is applied by default by the ``HttpMessageExchange`` and any ``ClientTransport``‘s that use - the exchange. + This plugin is applied by default by all built-in HTTP transports. The added agent header has the form: