@aws/nx-plugin-mcp 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/aws-nx-mcp.js +17 -9
- package/docs/get_started/existing-project.mdx +1 -1
- package/docs/get_started/quick-start.mdx +38 -54
- package/docs/get_started/tutorials/contribute-generator.mdx +5 -5
- package/docs/get_started/tutorials/dungeon-game/1.mdx +17 -17
- package/docs/get_started/tutorials/dungeon-game/overview.mdx +4 -70
- package/docs/guides/agentcore-gateway.mdx +2 -26
- package/docs/guides/connection/agentcore-gateway-agent.mdx +1 -1
- package/docs/guides/connection/py-agent-a2a.mdx +2 -2
- package/docs/guides/connection/py-agent-gateway.mdx +1 -1
- package/docs/guides/connection/py-agent-mcp.mdx +1 -1
- package/docs/guides/connection/react-trpc.mdx +1 -1
- package/docs/guides/connection/react-ts-agent.mdx +1 -1
- package/docs/guides/open-api-py-client.mdx +270 -0
- package/docs/guides/py-dynamodb.mdx +7 -0
- package/docs/guides/react-website-auth.mdx +3 -33
- package/docs/guides/react-website.mdx +3 -28
- package/docs/guides/runtime-config.mdx +2 -34
- package/docs/guides/terraform-project.mdx +1 -1
- package/docs/guides/ts-dynamodb.mdx +7 -0
- package/docs/guides/ts-smithy-api.mdx +8 -47
- package/docs/guides/typescript-project.mdx +2 -2
- package/docs/guides/workspace.mdx +7 -10
- package/docs/snippets/agent/architecture.mdx +9 -52
- package/docs/snippets/agent/bedrock-deployment.mdx +1 -1
- package/docs/snippets/agent/runtime-arn.mdx +1 -1
- package/docs/snippets/api/access-logging.mdx +1 -1
- package/docs/snippets/api/api-architecture.mdx +4 -75
- package/docs/snippets/api/type-safe-api-integrations.mdx +2 -4
- package/docs/snippets/lambda-function/architecture.mdx +3 -29
- package/docs/snippets/mcp/architecture.mdx +9 -38
- package/docs/snippets/mcp/bedrock-deployment.mdx +1 -1
- package/docs/snippets/pdk-migration/example/01-migrate-api.mdx +1 -1
- package/docs/snippets/pdk-migration/example/02-migrate-website.mdx +5 -6
- package/docs/snippets/pdk-migration/example/03-migrate-infra.mdx +1 -1
- package/docs/snippets/pdk-migration/faq/type-safe-api.mdx +2 -2
- package/docs/snippets/rdb/architecture.mdx +2 -33
- package/generators.json +7 -0
- package/package.json +1 -1
- package/src/agentcore-gateway/schema.json +1 -0
- package/src/open-api/py-client/schema.json +28 -0
- package/src/py/agent/schema.json +2 -0
- package/src/py/mcp-server/schema.json +1 -0
- package/src/ts/agent/schema.json +1 -0
- package/src/ts/api/schema.json +2 -0
- package/src/ts/mcp-server/schema.json +1 -0
- package/src/ts/react-website/app/schema.json +1 -0
- package/src/ts/website/app/schema.json +1 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: OpenAPI Python Client
|
|
3
|
+
description: Reference documentation for the OpenAPI Python client generator
|
|
4
|
+
generator: open-api#py-client
|
|
5
|
+
sidebar:
|
|
6
|
+
# Hidden until a connection generator vends this client, matching the
|
|
7
|
+
# generator's own `hidden: true`.
|
|
8
|
+
hidden: true
|
|
9
|
+
---
|
|
10
|
+
import { FileTree } from '@astrojs/starlight/components';
|
|
11
|
+
import GeneratorParameters from '@components/generator-parameters.astro';
|
|
12
|
+
import RunGenerator from '@components/run-generator.astro';
|
|
13
|
+
import Drawer from '@components/drawer.astro';
|
|
14
|
+
|
|
15
|
+
Generate a type-safe Python client for any OpenAPI specification, built on [httpx](https://www.python-httpx.org/) and [pydantic](https://docs.pydantic.dev/).
|
|
16
|
+
|
|
17
|
+
The client is the Python counterpart of the `open-api#ts-client` generator: one class per API, keyword-only methods, typed errors you can narrow, and a single extension point — your own `httpx` client — for authentication and anything else you need on the wire.
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
<RunGenerator generator="open-api#py-client" />
|
|
22
|
+
|
|
23
|
+
### Options
|
|
24
|
+
|
|
25
|
+
<GeneratorParameters generator="open-api#py-client" />
|
|
26
|
+
|
|
27
|
+
## Generator Output
|
|
28
|
+
|
|
29
|
+
<FileTree>
|
|
30
|
+
|
|
31
|
+
- \<outputPath>
|
|
32
|
+
- \_\_init\_\_.py Exports the clients, `ApiError` and the `types` module
|
|
33
|
+
- types.py pydantic models for every schema in the specification
|
|
34
|
+
- errors.py `ApiError` and a subclass per operation
|
|
35
|
+
- client.py Synchronous client, using `httpx.Client`
|
|
36
|
+
- async_client.py Asynchronous client, using `httpx.AsyncClient`
|
|
37
|
+
|
|
38
|
+
</FileTree>
|
|
39
|
+
|
|
40
|
+
Pass `--clientType=sync` or `--clientType=async` to emit just one of the two clients.
|
|
41
|
+
|
|
42
|
+
:::tip[Generated Client in Git]
|
|
43
|
+
The client is ignored from version control by default, since it is regenerated from the specification. Remove the entry from your `.gitignore` to check it in instead — but note that any manual edits will be overwritten the next time it is generated.
|
|
44
|
+
:::
|
|
45
|
+
|
|
46
|
+
### Dependencies
|
|
47
|
+
|
|
48
|
+
The generated code imports `httpx` and `pydantic`, so add both to the project you generate into:
|
|
49
|
+
|
|
50
|
+
```toml
|
|
51
|
+
# pyproject.toml
|
|
52
|
+
dependencies = [
|
|
53
|
+
"httpx>=0.28.1",
|
|
54
|
+
"pydantic>=2.13.4",
|
|
55
|
+
]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Nothing else is required — no runtime of its own, and no framework to adopt.
|
|
59
|
+
|
|
60
|
+
## Using the Generated Client
|
|
61
|
+
|
|
62
|
+
Instantiate the client with the API's base URL:
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from my_api import MyApi, MyApiConfig
|
|
66
|
+
|
|
67
|
+
api = MyApi(MyApiConfig(url="https://api.example.com"))
|
|
68
|
+
|
|
69
|
+
pet = api.pet.add_pet(name="rex", status="available")
|
|
70
|
+
print(pet.id, pet.name)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Methods are **keyword-only**, so a call reads as the specification does, and required parameters come first:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
pets = api.pet.list_pets(status=["available"], limit=10)
|
|
77
|
+
pet = api.pet.get_pet_by_id(pet_id=42)
|
|
78
|
+
api.pet.delete_pet(pet_id=42)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Operations tagged in the specification are grouped into namespaces — `api.pet.add_pet(...)` above comes from the `pet` tag. Untagged operations sit directly on the client, as `api.health()`.
|
|
82
|
+
|
|
83
|
+
An operation whose body is an object has its fields flattened into the call, so there is no wrapper to construct. Where the body is a list or a dictionary it is passed positionally instead:
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
created = api.pet.batch_create([types.Pet(name="a"), types.Pet(name="b")])
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Types
|
|
90
|
+
|
|
91
|
+
Every schema becomes a pydantic model in `types`, so results are validated and your editor knows their shape:
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from my_api import types
|
|
95
|
+
|
|
96
|
+
pet = api.pet.add_pet(name="rex", owner=types.Owner(name="ann"))
|
|
97
|
+
|
|
98
|
+
reveal_type(pet) # types.Pet
|
|
99
|
+
reveal_type(pet.owner) # types.Owner | None
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Enums become `Literal` types, so an invalid value is a type error rather than a failed request:
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
api.pet.list_pets(status=["available"]) # ok
|
|
106
|
+
api.pet.list_pets(status=["on-mars"]) # rejected before it is sent
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Dates and date-times are `datetime.date` / `datetime.datetime` on the way in and out — the client handles the ISO-8601 conversion:
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
event = api.create_event(day=datetime.date(2026, 4, 18))
|
|
113
|
+
reveal_type(event.day) # datetime.date
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Errors
|
|
117
|
+
|
|
118
|
+
A non-success response raises an exception. Catch `ApiError` to handle any failure from either client:
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
from my_api import ApiError
|
|
122
|
+
|
|
123
|
+
try:
|
|
124
|
+
pet = api.pet.get_pet_by_id(pet_id=42)
|
|
125
|
+
except ApiError as e:
|
|
126
|
+
print(e.status, e.error)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Each operation also has its own subclass, whose `.error` narrows to the responses that operation declares. `isinstance` picks out one status:
|
|
130
|
+
|
|
131
|
+
```python {8,10}
|
|
132
|
+
from my_api import types
|
|
133
|
+
from my_api.errors import GetPetByIdApiError
|
|
134
|
+
|
|
135
|
+
try:
|
|
136
|
+
pet = api.pet.get_pet_by_id(pet_id=42)
|
|
137
|
+
except GetPetByIdApiError as e:
|
|
138
|
+
if isinstance(e.error, types.GetPetById404Error):
|
|
139
|
+
print("no such pet:", e.error.error.detail)
|
|
140
|
+
else:
|
|
141
|
+
print("failed with", e.status)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
There is one class per response the operation declares, named after its status code — a declared `4XX` range becomes `GetPetById4XXError`.
|
|
145
|
+
|
|
146
|
+
A body that doesn't match the schema the specification declares still raises the typed exception, carrying whatever the server actually sent — so a proxy's HTML error page surfaces as an error rather than a validation failure inside your error handler.
|
|
147
|
+
|
|
148
|
+
### Streaming
|
|
149
|
+
|
|
150
|
+
An operation that streams returns an iterator of parsed items, so you can consume the response as it arrives:
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
for chunk in api.stream_chunks(count=4):
|
|
154
|
+
print(chunk.index, chunk.message)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Async
|
|
158
|
+
|
|
159
|
+
The async client mirrors the sync one, method for method:
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
from my_api import AsyncMyApi, AsyncMyApiConfig
|
|
163
|
+
|
|
164
|
+
async with AsyncMyApi(AsyncMyApiConfig(url="https://api.example.com")) as api:
|
|
165
|
+
pet = await api.pet.add_pet(name="rex")
|
|
166
|
+
|
|
167
|
+
async for chunk in api.stream_chunks(count=4):
|
|
168
|
+
print(chunk.message)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Both clients raise from the same hierarchy, so `except ApiError` catches either.
|
|
172
|
+
|
|
173
|
+
## Authentication
|
|
174
|
+
|
|
175
|
+
Authentication is the one thing every API does differently, so the client doesn't invent an abstraction for it. Supply your own `httpx` client and whatever you configure on it applies to every request:
|
|
176
|
+
|
|
177
|
+
```python {6,13}
|
|
178
|
+
import httpx
|
|
179
|
+
from my_api import MyApi, MyApiConfig
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class BearerAuth(httpx.Auth):
|
|
183
|
+
def __init__(self, token: str) -> None:
|
|
184
|
+
self.token = token
|
|
185
|
+
|
|
186
|
+
def auth_flow(self, request):
|
|
187
|
+
request.headers["Authorization"] = f"Bearer {self.token}"
|
|
188
|
+
yield request
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
with httpx.Client(auth=BearerAuth("my-token")) as http:
|
|
192
|
+
api = MyApi(MyApiConfig(url="https://api.example.com", httpx_client=http))
|
|
193
|
+
pet = api.pet.add_pet(name="rex")
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
This is the Python equivalent of passing a custom `fetch` to the TypeScript client. An [`httpx.Auth`](https://www.python-httpx.org/advanced/authentication/), event hooks, a custom transport, timeouts, retries, proxies, HTTP/2, and the client's own headers and query parameters all apply — including on multipart uploads and streaming responses.
|
|
197
|
+
|
|
198
|
+
A client you supply is never closed by the generated one, so it is safe to share across several clients.
|
|
199
|
+
|
|
200
|
+
<Drawer title="Signing requests with AWS SigV4" trigger="Click here for an example which signs requests with AWS IAM credentials.">
|
|
201
|
+
|
|
202
|
+
`httpx.Auth` is all a signer needs to be. For an API behind IAM authentication:
|
|
203
|
+
|
|
204
|
+
```python
|
|
205
|
+
import hashlib
|
|
206
|
+
from collections.abc import Generator
|
|
207
|
+
|
|
208
|
+
import boto3
|
|
209
|
+
import httpx
|
|
210
|
+
from botocore.auth import SigV4Auth
|
|
211
|
+
from botocore.awsrequest import AWSRequest
|
|
212
|
+
|
|
213
|
+
from my_api import MyApi, MyApiConfig
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
class SigV4HTTPXAuth(httpx.Auth):
|
|
217
|
+
requires_request_body = True
|
|
218
|
+
|
|
219
|
+
def __init__(self, credentials, service: str, region: str):
|
|
220
|
+
self.signer = SigV4Auth(credentials, service, region)
|
|
221
|
+
|
|
222
|
+
def auth_flow(
|
|
223
|
+
self, request: httpx.Request
|
|
224
|
+
) -> Generator[httpx.Request, httpx.Response]:
|
|
225
|
+
headers = dict(request.headers)
|
|
226
|
+
headers.pop("connection", None)
|
|
227
|
+
headers["x-amz-content-sha256"] = hashlib.sha256(
|
|
228
|
+
request.content or b""
|
|
229
|
+
).hexdigest()
|
|
230
|
+
|
|
231
|
+
aws_request = AWSRequest(
|
|
232
|
+
method=request.method,
|
|
233
|
+
url=str(request.url),
|
|
234
|
+
data=request.content,
|
|
235
|
+
headers=headers,
|
|
236
|
+
)
|
|
237
|
+
self.signer.add_auth(aws_request)
|
|
238
|
+
|
|
239
|
+
request.headers.clear()
|
|
240
|
+
request.headers.update(dict(aws_request.headers))
|
|
241
|
+
yield request
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
session = boto3.Session()
|
|
245
|
+
auth = SigV4HTTPXAuth(session.get_credentials(), "execute-api", session.region_name)
|
|
246
|
+
|
|
247
|
+
with httpx.Client(auth=auth) as http:
|
|
248
|
+
api = MyApi(MyApiConfig(url="https://api.example.com", httpx_client=http))
|
|
249
|
+
pet = api.pet.add_pet(name="rex")
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
</Drawer>
|
|
253
|
+
|
|
254
|
+
### Other configuration
|
|
255
|
+
|
|
256
|
+
`Config` carries a small number of options beyond the URL and the client:
|
|
257
|
+
|
|
258
|
+
```python
|
|
259
|
+
api = MyApi(
|
|
260
|
+
MyApiConfig(
|
|
261
|
+
url="https://api.example.com",
|
|
262
|
+
# Sent with every request, where the operation sets no header of its own
|
|
263
|
+
headers={"x-tenant-id": "acme"},
|
|
264
|
+
# Omit the Content-Type the specification declares for each request
|
|
265
|
+
omit_content_type_header=False,
|
|
266
|
+
)
|
|
267
|
+
)
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
A header an operation sets always wins over the same header here, so a per-call value is never merged into the configured one.
|
|
@@ -11,6 +11,7 @@ import Link from '@components/link.astro';
|
|
|
11
11
|
import RunGenerator from '@components/run-generator.astro';
|
|
12
12
|
import GeneratorParameters from '@components/generator-parameters.astro';
|
|
13
13
|
import Snippet from '@components/snippet.astro';
|
|
14
|
+
import ArchitectureDiagram from '@components/architecture-diagram.astro';
|
|
14
15
|
|
|
15
16
|
This generator creates a new Python project backed by [Amazon DynamoDB](https://aws.amazon.com/dynamodb/), using [PynamoDB](https://pynamodb.readthedocs.io/) for entity modelling. It generates the application code and infrastructure needed to provision and manage a DynamoDB table using AWS CDK or Terraform, with single-table design support and built-in local development via DynamoDB Local.
|
|
16
17
|
|
|
@@ -53,6 +54,12 @@ The local development scripts are shared across all DynamoDB projects (both Type
|
|
|
53
54
|
|
|
54
55
|
<Snippet name="dynamodb/infrastructure" />
|
|
55
56
|
|
|
57
|
+
#### Architecture
|
|
58
|
+
|
|
59
|
+
The deployed project provisions the table itself, which any project it is connected to reads and writes:
|
|
60
|
+
|
|
61
|
+
<ArchitectureDiagram />
|
|
62
|
+
|
|
56
63
|
## Local Development
|
|
57
64
|
|
|
58
65
|
### Starting Local DynamoDB
|
|
@@ -10,6 +10,7 @@ import GeneratorParameters from '@components/generator-parameters.astro';
|
|
|
10
10
|
import NxCommands from '@components/nx-commands.astro';
|
|
11
11
|
import Infrastructure from '@components/infrastructure.astro';
|
|
12
12
|
import Snippet from '@components/snippet.astro';
|
|
13
|
+
import ArchitectureDiagram from '@components/architecture-diagram.astro';
|
|
13
14
|
|
|
14
15
|
The React Website Authentication generator adds authentication to your React website using [Amazon Cognito](https://aws.amazon.com/cognito/).
|
|
15
16
|
|
|
@@ -71,38 +72,7 @@ You will also find the following infrastructure code generated based on your sel
|
|
|
71
72
|
|
|
72
73
|
This generator adds an Amazon Cognito user pool (for sign-in) and an identity pool (for federating signed-in users to scoped IAM credentials) to the existing static-website architecture:
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
direction: right
|
|
76
|
-
|
|
77
|
-
browser: Web Browser {
|
|
78
|
-
shape: image
|
|
79
|
-
icon: /nx-plugin-for-aws/icons/aws/client.svg
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
waf: WAF {
|
|
83
|
-
shape: image
|
|
84
|
-
icon: /nx-plugin-for-aws/icons/aws/waf.svg
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
cognito: Cognito\n(User + Identity Pool) {
|
|
88
|
-
shape: image
|
|
89
|
-
icon: /nx-plugin-for-aws/icons/aws/cognito.svg
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
iam: Scoped IAM\nCredentials {
|
|
93
|
-
shape: image
|
|
94
|
-
icon: /nx-plugin-for-aws/icons/aws/iam.svg
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
backend: Authenticated\nAWS Resources {
|
|
98
|
-
shape: rectangle
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
browser -> waf: Sign in
|
|
102
|
-
waf -> cognito
|
|
103
|
-
cognito -> iam
|
|
104
|
-
browser -> backend: IAM/Cognito
|
|
105
|
-
```
|
|
75
|
+
<ArchitectureDiagram name="my-website" />
|
|
106
76
|
|
|
107
77
|
#### Threat protection
|
|
108
78
|
|
|
@@ -255,7 +225,7 @@ In order to grant authenticated users access to perform certain actions, such as
|
|
|
255
225
|
|
|
256
226
|
<Infrastructure>
|
|
257
227
|
<Fragment slot="cdk">
|
|
258
|
-
```ts title="packages/infra/src/stacks/application-stack.ts" {
|
|
228
|
+
```ts title="packages/infra/src/stacks/application-stack.ts" {14}
|
|
259
229
|
import { Stack, StackProps } from 'aws-cdk-lib';
|
|
260
230
|
import { Construct } from 'constructs';
|
|
261
231
|
import { MyWebsite, UserIdentity, MyApi } from '@my-scope/common-constructs';
|
|
@@ -17,6 +17,7 @@ import PackageManagerShortCommand from '@components/package-manager-short-comman
|
|
|
17
17
|
import Infrastructure from '@components/infrastructure.astro';
|
|
18
18
|
import Snippet from '@components/snippet.astro';
|
|
19
19
|
import OptionFilter from '@components/option-filter.astro';
|
|
20
|
+
import ArchitectureDiagram from '@components/architecture-diagram.astro';
|
|
20
21
|
|
|
21
22
|
This generator creates a new [React](https://react.dev/) website with [shadcn/ui](https://ui.shadcn.com/) configured by default, along with the AWS CDK or Terraform infrastructure to deploy your website to the cloud as a static website hosted in [S3](https://aws.amazon.com/s3/), served by [CloudFront](https://aws.amazon.com/cloudfront/) and protected by [WAF](https://aws.amazon.com/waf/).
|
|
22
23
|
|
|
@@ -106,35 +107,9 @@ The generator creates infrastructure as code for deploying your website based on
|
|
|
106
107
|
|
|
107
108
|
#### Architecture
|
|
108
109
|
|
|
109
|
-
The deployed website has the following architecture:
|
|
110
|
+
The deployed website has the following architecture: your built assets in an S3 bucket, served by a CloudFront distribution with an AWS WAFv2 Web ACL in front of it.
|
|
110
111
|
|
|
111
|
-
|
|
112
|
-
direction: right
|
|
113
|
-
|
|
114
|
-
browser: Web Browser {
|
|
115
|
-
shape: image
|
|
116
|
-
icon: /nx-plugin-for-aws/icons/aws/client.svg
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
waf: WAF {
|
|
120
|
-
shape: image
|
|
121
|
-
icon: /nx-plugin-for-aws/icons/aws/waf.svg
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
cloudfront: CloudFront {
|
|
125
|
-
shape: image
|
|
126
|
-
icon: /nx-plugin-for-aws/icons/aws/cloudfront.svg
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
s3: Static Assets\n(S3) {
|
|
130
|
-
shape: image
|
|
131
|
-
icon: /nx-plugin-for-aws/icons/aws/s3.svg
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
browser -> waf
|
|
135
|
-
waf -> cloudfront
|
|
136
|
-
cloudfront -> s3
|
|
137
|
-
```
|
|
112
|
+
<ArchitectureDiagram />
|
|
138
113
|
|
|
139
114
|
## Implementing your Website
|
|
140
115
|
|
|
@@ -5,6 +5,7 @@ description: How runtime configuration connects your generated projects using AW
|
|
|
5
5
|
import { Tabs, TabItem, Steps } from '@astrojs/starlight/components';
|
|
6
6
|
import Infrastructure from '@components/infrastructure.astro';
|
|
7
7
|
import Link from '@components/link.astro';
|
|
8
|
+
import EmbeddedGraph from '@components/embedded-graph.astro';
|
|
8
9
|
|
|
9
10
|
Runtime configuration is the mechanism used by Nx Plugin for AWS to pass deploy-time values between generated projects and components so they can connect to one another. For example, when you generate an API, its URL is automatically registered in the runtime configuration so that a connected website can discover it.
|
|
10
11
|
|
|
@@ -26,40 +27,7 @@ The `connection` namespace is also deployed as a `runtime-config.json` file to y
|
|
|
26
27
|
|
|
27
28
|
You can define as many additional namespaces as you like, providing a convenient alternative to environment variables for passing deploy-time values to your Lambda functions or other compute resources.
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
direction: down
|
|
31
|
-
|
|
32
|
-
iac: "Infrastructure as code\nRuntimeConfig.set(...)"
|
|
33
|
-
|
|
34
|
-
appconfig: "AWS AppConfig" {
|
|
35
|
-
shape: cylinder
|
|
36
|
-
connection: "connection namespace"
|
|
37
|
-
agentcore: "agentcore namespace"
|
|
38
|
-
custom: "custom namespaces"
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
s3: "website S3 bucket" {
|
|
42
|
-
shape: cylinder
|
|
43
|
-
rcj: runtime-config.json {
|
|
44
|
-
shape: page
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
website: React website
|
|
49
|
-
|
|
50
|
-
server: Lambda / agent
|
|
51
|
-
|
|
52
|
-
iac -> appconfig.connection
|
|
53
|
-
iac -> appconfig.agentcore
|
|
54
|
-
iac -> appconfig.custom
|
|
55
|
-
|
|
56
|
-
appconfig.connection -> s3.rcj: deployed
|
|
57
|
-
s3.rcj -> website: fetched at load
|
|
58
|
-
|
|
59
|
-
appconfig.connection -> server
|
|
60
|
-
appconfig.agentcore -> server: Powertools getAppConfig
|
|
61
|
-
appconfig.custom -> server
|
|
62
|
-
```
|
|
30
|
+
<EmbeddedGraph diagram="runtime-config" />
|
|
63
31
|
|
|
64
32
|
## Infrastructure
|
|
65
33
|
|
|
@@ -89,7 +89,7 @@ Application projects include full deployment capabilities with remote state mana
|
|
|
89
89
|
|
|
90
90
|
You can start writing your Terraform infrastructure inside `src/main.tf`, for example:
|
|
91
91
|
|
|
92
|
-
```diff title="src/main.tf"
|
|
92
|
+
```diff title="src/main.tf"
|
|
93
93
|
-locals {
|
|
94
94
|
- account_id = data.aws_caller_identity.current.account_id
|
|
95
95
|
- aws_region = data.aws_region.current.id
|
|
@@ -11,6 +11,7 @@ import Link from '@components/link.astro';
|
|
|
11
11
|
import RunGenerator from '@components/run-generator.astro';
|
|
12
12
|
import GeneratorParameters from '@components/generator-parameters.astro';
|
|
13
13
|
import Snippet from '@components/snippet.astro';
|
|
14
|
+
import ArchitectureDiagram from '@components/architecture-diagram.astro';
|
|
14
15
|
|
|
15
16
|
This generator creates a new TypeScript DynamoDB project backed by [Amazon DynamoDB](https://aws.amazon.com/dynamodb/), using [ElectroDB](https://electrodb.dev/) for type-safe entity modelling. It generates the application code and infrastructure needed to provision and manage a DynamoDB table using AWS CDK or Terraform, with single-table design support and built-in local development via DynamoDB Local.
|
|
16
17
|
|
|
@@ -53,6 +54,12 @@ The local development scripts are shared across all DynamoDB projects (both Type
|
|
|
53
54
|
|
|
54
55
|
<Snippet name="dynamodb/infrastructure" />
|
|
55
56
|
|
|
57
|
+
#### Architecture
|
|
58
|
+
|
|
59
|
+
The deployed project provisions the table itself, which any project it is connected to reads and writes:
|
|
60
|
+
|
|
61
|
+
<ArchitectureDiagram />
|
|
62
|
+
|
|
56
63
|
## Local Development
|
|
57
64
|
|
|
58
65
|
### Starting Local DynamoDB
|
|
@@ -20,6 +20,7 @@ import Snippet from '@components/snippet.astro';
|
|
|
20
20
|
import OptionFilter from '@components/option-filter.astro';
|
|
21
21
|
import InstallCommand from '@components/install-command.astro';
|
|
22
22
|
import { TS_VERSIONS } from '../../../../../../packages/nx-plugin/src/utils/versions';
|
|
23
|
+
import ArchitectureDiagram from '@components/architecture-diagram.astro';
|
|
23
24
|
|
|
24
25
|
[Smithy](https://smithy.io/) is a protocol-agnostic interface definition language for authoring APIs in a model driven fashion.
|
|
25
26
|
|
|
@@ -126,47 +127,7 @@ This project is generated using the <Link path="/guides/terraform-project">`terr
|
|
|
126
127
|
|
|
127
128
|
The deployed Smithy API has the following architecture, with an [AWS WAFv2](https://docs.aws.amazon.com/waf/latest/developerguide/waf-chapter.html) Web ACL in front of the API Gateway stage:
|
|
128
129
|
|
|
129
|
-
|
|
130
|
-
direction: right
|
|
131
|
-
|
|
132
|
-
client: Client {
|
|
133
|
-
shape: image
|
|
134
|
-
icon: /nx-plugin-for-aws/icons/aws/client.svg
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
waf: WAF {
|
|
138
|
-
shape: image
|
|
139
|
-
icon: /nx-plugin-for-aws/icons/aws/waf.svg
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
apigw: API Gateway\n(REST API) {
|
|
143
|
-
shape: image
|
|
144
|
-
icon: /nx-plugin-for-aws/icons/aws/api-gateway.svg
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
lambda: Lambda\n(Smithy Server SDK) {
|
|
148
|
-
shape: image
|
|
149
|
-
icon: /nx-plugin-for-aws/icons/aws/lambda.svg
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
cw: CloudWatch\n(Logs, Metrics) {
|
|
153
|
-
shape: image
|
|
154
|
-
icon: /nx-plugin-for-aws/icons/aws/cloudwatch.svg
|
|
155
|
-
near: top-right
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
xray: X-Ray\n(Traces) {
|
|
159
|
-
shape: image
|
|
160
|
-
icon: /nx-plugin-for-aws/icons/aws/xray.svg
|
|
161
|
-
near: bottom-right
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
client -> waf
|
|
165
|
-
waf -> apigw
|
|
166
|
-
apigw -> lambda
|
|
167
|
-
lambda -> cw
|
|
168
|
-
lambda -> xray
|
|
169
|
-
```
|
|
130
|
+
<ArchitectureDiagram options={{ infra: 'rest-lambda' }} />
|
|
170
131
|
|
|
171
132
|
## Implementing your Smithy API
|
|
172
133
|
|
|
@@ -315,7 +276,7 @@ You must construct the context yourself in both `handler.ts` (the Lambda functio
|
|
|
315
276
|
|
|
316
277
|
The generator configures structured logging using AWS Lambda Powertools with automatic context injection via Middy middleware.
|
|
317
278
|
|
|
318
|
-
```typescript {
|
|
279
|
+
```typescript {4}
|
|
319
280
|
// handler.ts
|
|
320
281
|
export const handler = middy<APIGatewayProxyEvent, APIGatewayProxyResult>()
|
|
321
282
|
.use(captureLambdaHandler(tracer))
|
|
@@ -326,7 +287,7 @@ export const handler = middy<APIGatewayProxyEvent, APIGatewayProxyResult>()
|
|
|
326
287
|
|
|
327
288
|
You can reference the logger from your operation implementations via the context:
|
|
328
289
|
|
|
329
|
-
```typescript {
|
|
290
|
+
```typescript {6}
|
|
330
291
|
// operations/echo.ts
|
|
331
292
|
import { ServiceContext } from '../context.js';
|
|
332
293
|
import { Echo as EchoOperation } from '../generated/ssdk/index.js';
|
|
@@ -341,7 +302,7 @@ export const Echo: EchoOperation<ServiceContext> = async (input, ctx) => {
|
|
|
341
302
|
|
|
342
303
|
AWS X-Ray tracing is configured automatically via the `captureLambdaHandler` middleware.
|
|
343
304
|
|
|
344
|
-
```typescript {
|
|
305
|
+
```typescript {3}
|
|
345
306
|
// handler.ts
|
|
346
307
|
export const handler = middy<APIGatewayProxyEvent, APIGatewayProxyResult>()
|
|
347
308
|
.use(captureLambdaHandler(tracer))
|
|
@@ -352,7 +313,7 @@ export const handler = middy<APIGatewayProxyEvent, APIGatewayProxyResult>()
|
|
|
352
313
|
|
|
353
314
|
You can add custom subsegments to your traces in your operations:
|
|
354
315
|
|
|
355
|
-
```typescript {
|
|
316
|
+
```typescript {7, 11, 14}
|
|
356
317
|
// operations/echo.ts
|
|
357
318
|
import { ServiceContext } from '../context.js';
|
|
358
319
|
import { Echo as EchoOperation } from '../generated/ssdk/index.js';
|
|
@@ -375,7 +336,7 @@ export const Echo: EchoOperation<ServiceContext> = async (input, ctx) => {
|
|
|
375
336
|
|
|
376
337
|
CloudWatch metrics are collected automatically for each request via the `logMetrics` middleware.
|
|
377
338
|
|
|
378
|
-
```typescript {
|
|
339
|
+
```typescript {5}
|
|
379
340
|
// handler.ts
|
|
380
341
|
export const handler = middy<APIGatewayProxyEvent, APIGatewayProxyResult>()
|
|
381
342
|
.use(captureLambdaHandler(tracer))
|
|
@@ -386,7 +347,7 @@ export const handler = middy<APIGatewayProxyEvent, APIGatewayProxyResult>()
|
|
|
386
347
|
|
|
387
348
|
You can add custom metrics in your operations:
|
|
388
349
|
|
|
389
|
-
```typescript {
|
|
350
|
+
```typescript {7}
|
|
390
351
|
// operations/echo.ts
|
|
391
352
|
import { MetricUnit } from '@aws-lambda-powertools/metrics';
|
|
392
353
|
import { ServiceContext } from '../context.js';
|
|
@@ -228,9 +228,9 @@ npm has no catalog feature, so versions are declared directly in each `package.j
|
|
|
228
228
|
|
|
229
229
|
##### Opting out of catalogs
|
|
230
230
|
|
|
231
|
-
Catalogs are enabled by default. To turn them off, create your workspace with `--catalog
|
|
231
|
+
Catalogs are enabled by default. To turn them off, create your workspace with `--catalog=false`:
|
|
232
232
|
|
|
233
|
-
<CreateNxWorkspaceCommand workspace="my-project"
|
|
233
|
+
<CreateNxWorkspaceCommand workspace="my-project" values={{ catalog: false }} />
|
|
234
234
|
|
|
235
235
|
Or set it in `aws-nx-plugin.config.mts` at any time:
|
|
236
236
|
|
|
@@ -27,6 +27,7 @@ When you create a new workspace with `@aws/nx-plugin`, the preset generator sets
|
|
|
27
27
|
- package.json Root package.json for your monorepo
|
|
28
28
|
- nx.json Nx configuration (common targets, sync generators, caching)
|
|
29
29
|
- tsconfig.base.json Root TypeScript configuration
|
|
30
|
+
- biome.json Biome configuration for linting and formatting
|
|
30
31
|
- aws-nx-plugin.config.mts Nx Plugin for AWS configuration
|
|
31
32
|
- .git-secrets/ Vendored git-secrets bash script for credential scanning
|
|
32
33
|
- .gitallowed Patterns git-secrets treats as false positives
|
|
@@ -72,7 +73,7 @@ For details on how TypeScript and Python projects are set up, refer to the <Link
|
|
|
72
73
|
|
|
73
74
|
### Caching
|
|
74
75
|
|
|
75
|
-
Nx caches the output of previously executed targets and replays them when the inputs haven't changed. This dramatically speeds up builds, tests, and linting
|
|
76
|
+
Nx caches the output of previously executed targets and replays them when the inputs haven't changed. This dramatically speeds up builds, tests, and linting. If you encounter stale or unexpected behaviour, reset the cache with:
|
|
76
77
|
|
|
77
78
|
<NxCommands commands={['reset']} />
|
|
78
79
|
|
|
@@ -88,15 +89,7 @@ New workspaces set `parallel` in `nx.json`, which controls how many tasks Nx run
|
|
|
88
89
|
}
|
|
89
90
|
```
|
|
90
91
|
|
|
91
|
-
Lower it if you're building on a machine with fewer cores or limited memory:
|
|
92
|
-
|
|
93
|
-
```json title="nx.json"
|
|
94
|
-
{
|
|
95
|
-
"parallel": 3
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
You can also override it per-invocation:
|
|
92
|
+
Lower it if you're building on a machine with fewer cores or limited memory. You can also override it per-invocation:
|
|
100
93
|
|
|
101
94
|
<NxCommands commands={['run-many --target build --parallel=4']} />
|
|
102
95
|
|
|
@@ -166,6 +159,10 @@ This will run the chosen target as well as the targets it depends on.
|
|
|
166
159
|
|
|
167
160
|
New workspaces are configured with [Biome](https://biomejs.dev/) for static analysis and code formatting. Running `lint` checks all projects for issues, and `lint --configuration=fix` auto-fixes them.
|
|
168
161
|
|
|
162
|
+
### MCP Configuration
|
|
163
|
+
|
|
164
|
+
The plugin's <Link path="get_started/building-with-ai">MCP server</Link> is configured as a project level MCP server for Claude Code, Cursor, Kiro, Gemini CLI, GitHub Copilot and OpenAI Codex, so your coding assistant can discover and run the plugin's generators without any setup. The configuration is committed with your workspace, giving everyone on your team the same setup. Remove any configurations for coding assistants you and your team do not use.
|
|
165
|
+
|
|
169
166
|
### Git Secrets
|
|
170
167
|
|
|
171
168
|
Workspaces are set up with [git-secrets](https://github.com/awslabs/git-secrets) pre-commit hooks that scan staged files for AWS credential patterns before each commit. This prevents accidentally committing access keys, secret keys, and other sensitive values.
|