Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions smithy-templates.json
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@
".gitignore",
".gitattributes"
]
},
"smithy-typescript-minimal-aws-sdk": {
"documentation": "Minimal AWS SDK example using Smithy TypeScript",
"path": "smithy-typescript-examples/minimal-aws-sdk-client",
"include": [ ".gitignore", ".gitattributes" ]
}
}
}
17 changes: 17 additions & 0 deletions smithy-typescript-examples/minimal-aws-sdk-client/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
build:
@echo Building the minimal sdk...
yarn setup
@echo Successfully built minimal sdk.

clean:
@echo Cleaning...
rm -rf build
yarn clean
@echo Cleaning Complete.

run: build
@echo Running...
yarn start
@echo Finished running.

test-all: build
72 changes: 72 additions & 0 deletions smithy-typescript-examples/minimal-aws-sdk-client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
## Minimal AWS SDK Client

This project provides a template to get started using [Smithy TypeScript](https://github.com/smithy-lang/smithy-typescript/)
to create a minimal AWS SDK client (for DynamoDB).

For more information Smithy Typescript, see the [Smithy Typescript Quickstart Guide](https://smithy.io/2.0/typescript/quickstart.html).

### Layout

- `smithy-build.json`: A Smithy configuration file that defines how and what to build.
- `package.json`: The node project configuration file.
- `Makefile`: A makefile for quick usage of this project.
- `src/`: The code that uses the generated (minimal) client.

### Using as template
To use this example as a template run the following:

```console
smithy init -t smithy-typescript-minimal-aws-sdk
```

### Building and running the example

**NOTE**: This example assumes you have an existing AWS account, see [Additional Setup](#additional-setup) for preliminary instructions before running the example.

To build and run the example with one single command, run:
```console
make run
```
This command will build the minimal sdk from the smithy model, and then run the example code.

You can examine the generated code for the minimal (dynamodb) client under `sdk/`. You'll notice that under `src/commands`, there are only three commands generated for the operations we filtered! If you run `npm publish --dry-run` under `sdk/`, you can get an approximate size of our minimal client package. It's only ~40KB, which is approximately 1/5th the size of the full client (~200KB).

For cases where every byte counts, an AWS SDK client with only the operations you use can make a big difference.

### Caveats

#### Endpoints
With how AWS code-generators are written, some generator logic is tied heavily to how endpoints are modelled by AWS services. This example strips this information from the model before the generator is ran, and therefore endpoint-related code is not generated. This means that the client must have the endpoint set explicitly, otherwise it will not function:
```typescript
endpoint: {
protocol: 'https',
hostname: 'dynamodb.us-west-2.amazonaws.com',
port: 443,
path: '/'
},
region: 'us-west-2'
```

#### Incompatibilities
Given the above information, some AWS services require customizations by the AWS SDKs to correctly generate clients. Since we strip out endpoint information, those customizations may not function, and the client may not generate correctly. Therefore, your ability to generate a *working* minimal client for a given AWS service will vary.

#### Unsupported
Clients generated using the setup described here are not official SDK clients. Therefore, support for issues or problems encountered when using said generated clients will be limited.
Please use at your own risk.

### Additional Setup

Using the `aws-cli`, execute the following command to create the table used in this example:

```console
aws dynamodb --region us-west-2 create-table \
--table-name MyTestTable \
--attribute-definitions AttributeName=Id,AttributeType=S \
--key-schema AttributeName=Id,KeyType=HASH \
--billing-mode PAY_PER_REQUEST
```

To clean up and remove the table, run:
```console
aws dynamodb --region us-west-2 delete-table --table-name MyTestTable
```
28 changes: 28 additions & 0 deletions smithy-typescript-examples/minimal-aws-sdk-client/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "minimal-example",
"version": "0.0.1",
"description": "An example that can be used to experiment with the minimal client.",
"main": "dist/index.js",
"scripts": {
"build-model": "smithy build",
"link-sdk": "ln -fs build/smithy/minimal/typescript-client-codegen sdk",
"build-sdk": "cd sdk && yarn install && yarn build",
"clean-sdk": "rm -rf build/smithy/minimal/typescript-client-codegen/doc-client-*",
"setup": "yarn build-model && yarn link-sdk && yarn clean-sdk && yarn build-sdk && yarn install",
"start": "ts-node src/index.ts",
"repl": "ts-node",
"clean": "rm -rf build sdk node_modules dist"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"ts-node": "^10.9.2",
"typescript": "^5.4.5"
},
"dependencies": {
"@aws-sdk/client-dynamodb": "link:sdk",
"@types/node": "^20.12.13"
},
"packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"version": "1.0",
"maven": {
"dependencies": [
// The AWS API model dependency for DynamoDB
"software.amazon.api.models:dynamodb:(,1.0]",
// The TypeScript codegen dependencies
"software.amazon.smithy.typescript:smithy-aws-typescript-codegen:0.30.0",
"software.amazon.smithy.typescript:smithy-typescript-codegen:0.30.0"
]
},
"projections": {
"minimal": {
"transforms": [
// Strip out all operations that aren't given below
{
"name": "excludeShapesBySelector",
"args": {
"selector": "operation[id|name != ListTables] operation[id|name != GetItem] operation[id|name != PutItem]"
}
},
// Remove the endpoint rulesets because they don't play well without the full closure of operations
{
"name": "excludeTraits",
"args": {
"traits": ["smithy.rules#endpointRuleSet", "smithy.rules#endpointTests"]
}
},
// Remove any shapes that are unused (such as the inputs and outputs of removed operations)
{
"name": "removeUnusedShapes",
"args": {}
}
],
"plugins": {
"typescript-client-codegen": {
"package": "@aws-sdk/client-dynamodb",
"packageVersion": "0.0.1"
}
}
}
}
}
46 changes: 46 additions & 0 deletions smithy-typescript-examples/minimal-aws-sdk-client/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { DynamoDB }
from '@aws-sdk/client-dynamodb'

// Create the client, specifying the exact endpoint to use
const client = new DynamoDB({
endpoint: {
protocol: 'https',
hostname: 'dynamodb.us-west-2.amazonaws.com',
port: 443,
path: '/'
},
region: 'us-west-2'
})

async function main() {
console.log("\n\nDOOT DOOT.\n\n")

// Call `ListTables`, we assume you have a testing table in your account called 'MyTestTable'
let listTablesResponse = await client.listTables({})
// Log the response, there should be a list of tables under `TableName` (which includes 'MyTestTable')
console.log("ListTablesCommandOutput:", listTablesResponse)

// Call `PutItem` with the table (the table is the same table from above)
let putItemResponse = await client.putItem({
TableName: 'MyTestTable',
Item: {
'Id': { S: '0' },
'Name': { S: 'abc123' }
}
})
// Log the response, there should a '200' in `$metadata.httpStatusCode`
console.log("PutItemCommandOutput:", putItemResponse)

// Call `GetItem` to get the item we created above
let getItemResponse = await client.getItem({
TableName: 'MyTestTable',
Key: {
'Id': { S: '0' }
}
})
// Log the response, we should see the item under the `Item` field
console.log("GetItemCommandOutput:", getItemResponse)

}

main().catch(error => console.error("Unhandled error:", error));
Loading