-
Notifications
You must be signed in to change notification settings - Fork 5.8k
JavaScript code example standards
-
javascriptv3
is considered the project root. - All examples exist under
example_code
. - Each directory under
example_code
corresponds to an AWS service. - Directory names should be lowercase with underscores.
- File names should be lowercase with dashes.
-
cross-services
is a special directory for examples that use multiple services. - A service directory typically has the following structure:
-
actions/ {action-name}.js scenarios/ web/ {web-scenario-name}/ {scenario-name}.js {scenario_folder}/ {scenario-file}.js tests/ {integ-test-name}.integration.test.js {unit-test-name}.unit.test.js package.json README.md vite.config.js
-
When an file needs to be run from the command line, add the following code to the bottom. This ensures the file can be run directly, or imported.
// Call function if run directly
import { fileURLToPath } from "url";
if (process.argv[1] === fileURLToPath(import.meta.url)) {
example();
}
Previous versions of the AWS SDK for JavaScript were less modularized. The latest versions rely heavily on modular packages. Import only the clients and commands needed.
import { ListBucketsCommand, S3Client } from "@aws-sdk/client-s3";
const client = new S3Client({});
export const helloS3 = async () => {
const command = new ListBucketsCommand({});
const { Buckets } = await client.send(command);
console.log("Buckets: ");
console.log(Buckets.map((bucket) => bucket.Name).join("\n"));
return Buckets;
};
While it's tempting to abstract things like client instantiation, it's more educational to show such things in close proximity. Over abstraction makes it harder for a customer to understand what's happening.
const createFunction = async (funcName, roleArn) => {
const client = new LambdaClient({});
const code = await readFile(`${dirname}../functions/${funcName}.zip`);
const command = new CreateFunctionCommand({
Code: { ZipFile: code },
FunctionName: funcName,
Role: roleArn,
Architectures: [Architecture.arm64],
Handler: "index.handler", // Required when sending a .zip file
PackageType: PackageType.Zip, // Required when sending a .zip file
Runtime: Runtime.nodejs16x, // Required when sending a .zip file
});
return client.send(command);
};
Some examples are more complicated than just singular client calls. In cases like these, there should be a balance between education and engineering. javascriptv3/example_code/libs/scenario
is a module that provides a framework for setting up more complex examples. Use this framework when an example is more than a few steps.
For guidance on using the scenario framework, see javascriptv3/example_code/libs/scenario/scenario-example.js
.
If an example is contained within one file, use snippet_files
in the metadata instead of snippet_tags
.
Unit tests are nice. Integration tests are required. The goal of the integration testing is to ensure our examples are fresh and haven't suffered breaking changes from the services.
Adhere to the following principles when creating integration tests:
- Ensure proper setup an tear down. Any resources created for the test should be deleted by the test.
- At minimum, ensure example code does not error.
If you modify an example, refactor it to match these standards.