Skip to content

Commit 68c5ddb

Browse files
authored
Merge pull request #135 from smithy-lang/haydenbaker/min-aws-sdk
Add smithy-typescript minimal aws sdk example
2 parents fb6654a + aff0cc2 commit 68c5ddb

File tree

6 files changed

+211
-0
lines changed

6 files changed

+211
-0
lines changed

smithy-templates.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@
163163
".gitignore",
164164
".gitattributes"
165165
]
166+
},
167+
"smithy-typescript-minimal-aws-sdk": {
168+
"documentation": "Minimal AWS SDK example using Smithy TypeScript",
169+
"path": "smithy-typescript-examples/minimal-aws-sdk-client",
170+
"include": [ ".gitignore", ".gitattributes" ]
166171
}
167172
}
168173
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
build:
2+
@echo Building the minimal sdk...
3+
yarn setup
4+
@echo Successfully built minimal sdk.
5+
6+
clean:
7+
@echo Cleaning...
8+
rm -rf build
9+
yarn clean
10+
@echo Cleaning Complete.
11+
12+
run: build
13+
@echo Running...
14+
yarn start
15+
@echo Finished running.
16+
17+
test-all: build
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
## Minimal AWS SDK Client
2+
3+
This project provides a template to get started using [Smithy TypeScript](https://github.com/smithy-lang/smithy-typescript/)
4+
to create a minimal AWS SDK client (for DynamoDB).
5+
6+
For more information Smithy Typescript, see the [Smithy Typescript Quickstart Guide](https://smithy.io/2.0/typescript/quickstart.html).
7+
8+
### Layout
9+
10+
- `smithy-build.json`: A Smithy configuration file that defines how and what to build.
11+
- `package.json`: The node project configuration file.
12+
- `Makefile`: A makefile for quick usage of this project.
13+
- `src/`: The code that uses the generated (minimal) client.
14+
15+
### Using as template
16+
To use this example as a template run the following:
17+
18+
```console
19+
smithy init -t smithy-typescript-minimal-aws-sdk
20+
```
21+
22+
### Building and running the example
23+
24+
**NOTE**: This example assumes you have an existing AWS account, see [Additional Setup](#additional-setup) for preliminary instructions before running the example.
25+
26+
To build and run the example with one single command, run:
27+
```console
28+
make run
29+
```
30+
This command will build the minimal sdk from the smithy model, and then run the example code.
31+
32+
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).
33+
34+
For cases where every byte counts, an AWS SDK client with only the operations you use can make a big difference.
35+
36+
### Caveats
37+
38+
#### Endpoints
39+
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:
40+
```typescript
41+
endpoint: {
42+
protocol: 'https',
43+
hostname: 'dynamodb.us-west-2.amazonaws.com',
44+
port: 443,
45+
path: '/'
46+
},
47+
region: 'us-west-2'
48+
```
49+
50+
#### Incompatibilities
51+
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.
52+
53+
#### Unsupported
54+
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.
55+
Please use at your own risk.
56+
57+
### Additional Setup
58+
59+
Using the `aws-cli`, execute the following command to create the table used in this example:
60+
61+
```console
62+
aws dynamodb --region us-west-2 create-table \
63+
--table-name MyTestTable \
64+
--attribute-definitions AttributeName=Id,AttributeType=S \
65+
--key-schema AttributeName=Id,KeyType=HASH \
66+
--billing-mode PAY_PER_REQUEST
67+
```
68+
69+
To clean up and remove the table, run:
70+
```console
71+
aws dynamodb --region us-west-2 delete-table --table-name MyTestTable
72+
```
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "minimal-example",
3+
"version": "0.0.1",
4+
"description": "An example that can be used to experiment with the minimal client.",
5+
"main": "dist/index.js",
6+
"scripts": {
7+
"build-model": "smithy build",
8+
"link-sdk": "ln -fs build/smithy/minimal/typescript-client-codegen sdk",
9+
"build-sdk": "cd sdk && yarn install && yarn build",
10+
"clean-sdk": "rm -rf build/smithy/minimal/typescript-client-codegen/doc-client-*",
11+
"setup": "yarn build-model && yarn link-sdk && yarn clean-sdk && yarn build-sdk && yarn install",
12+
"start": "ts-node src/index.ts",
13+
"repl": "ts-node",
14+
"clean": "rm -rf build sdk node_modules dist"
15+
},
16+
"keywords": [],
17+
"author": "",
18+
"license": "ISC",
19+
"devDependencies": {
20+
"ts-node": "^10.9.2",
21+
"typescript": "^5.4.5"
22+
},
23+
"dependencies": {
24+
"@aws-sdk/client-dynamodb": "link:sdk",
25+
"@types/node": "^20.12.13"
26+
},
27+
"packageManager": "[email protected]+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
28+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"version": "1.0",
3+
"maven": {
4+
"dependencies": [
5+
// The AWS API model dependency for DynamoDB
6+
"software.amazon.api.models:dynamodb:(,1.0]",
7+
// The TypeScript codegen dependencies
8+
"software.amazon.smithy.typescript:smithy-aws-typescript-codegen:0.30.0",
9+
"software.amazon.smithy.typescript:smithy-typescript-codegen:0.30.0"
10+
]
11+
},
12+
"projections": {
13+
"minimal": {
14+
"transforms": [
15+
// Strip out all operations that aren't given below
16+
{
17+
"name": "excludeShapesBySelector",
18+
"args": {
19+
"selector": "operation[id|name != ListTables] operation[id|name != GetItem] operation[id|name != PutItem]"
20+
}
21+
},
22+
// Remove the endpoint rulesets because they don't play well without the full closure of operations
23+
{
24+
"name": "excludeTraits",
25+
"args": {
26+
"traits": ["smithy.rules#endpointRuleSet", "smithy.rules#endpointTests"]
27+
}
28+
},
29+
// Remove any shapes that are unused (such as the inputs and outputs of removed operations)
30+
{
31+
"name": "removeUnusedShapes",
32+
"args": {}
33+
}
34+
],
35+
"plugins": {
36+
"typescript-client-codegen": {
37+
"package": "@aws-sdk/client-dynamodb",
38+
"packageVersion": "0.0.1"
39+
}
40+
}
41+
}
42+
}
43+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { DynamoDB }
2+
from '@aws-sdk/client-dynamodb'
3+
4+
// Create the client, specifying the exact endpoint to use
5+
const client = new DynamoDB({
6+
endpoint: {
7+
protocol: 'https',
8+
hostname: 'dynamodb.us-west-2.amazonaws.com',
9+
port: 443,
10+
path: '/'
11+
},
12+
region: 'us-west-2'
13+
})
14+
15+
async function main() {
16+
console.log("\n\nDOOT DOOT.\n\n")
17+
18+
// Call `ListTables`, we assume you have a testing table in your account called 'MyTestTable'
19+
let listTablesResponse = await client.listTables({})
20+
// Log the response, there should be a list of tables under `TableName` (which includes 'MyTestTable')
21+
console.log("ListTablesCommandOutput:", listTablesResponse)
22+
23+
// Call `PutItem` with the table (the table is the same table from above)
24+
let putItemResponse = await client.putItem({
25+
TableName: 'MyTestTable',
26+
Item: {
27+
'Id': { S: '0' },
28+
'Name': { S: 'abc123' }
29+
}
30+
})
31+
// Log the response, there should a '200' in `$metadata.httpStatusCode`
32+
console.log("PutItemCommandOutput:", putItemResponse)
33+
34+
// Call `GetItem` to get the item we created above
35+
let getItemResponse = await client.getItem({
36+
TableName: 'MyTestTable',
37+
Key: {
38+
'Id': { S: '0' }
39+
}
40+
})
41+
// Log the response, we should see the item under the `Item` field
42+
console.log("GetItemCommandOutput:", getItemResponse)
43+
44+
}
45+
46+
main().catch(error => console.error("Unhandled error:", error));

0 commit comments

Comments
 (0)