Appalling inconsistencies in AWS SDK for JavaScript v3

Been using the AWS SDK for JavaScript v3 for the past 2 weeks and was bitten many times by the appalling inconsistencies, not to mention the unnecessary verbosity of the naming conventions, making it painful to write code to handle the requests/responses in a generic way across all the resources.

A picture paints a thousand words, so the best way to show this would be via a comparison table, with the inconsistencies marked out in red. The biggest gotcha for me was the DescribeNatGatewaysCommand, where I kept wondering why my filter criteria did not work. Turns out that it uses Filter instead of Filters which the Describe commands for the other resources use. The AWS SDK uses TypeScript – isn’t that supposed to catch these types of errors? Was the SDK designed such that all Describe commands across all resources implement a common interface or extend a base AbstractDescribeCommand class?

As the article Discipline Makes Strong Developers states, “Discipline. Discipline! I repeat it because the mere presence of a great source control system doesn’t obligate anyone to use it in a structured, rational way. No. That takes discipline.”, the same goes for TypeScript. You and everyone on your team needs to have discipline to design all the types, interfaces and classes properly at all times (not just initially but for new features as well), and then use them properly at all times, or else you are better off just using plain vanilla JavaScript without all the transpiling overheads (cos TypeScript does not run natively in the browser nor in Node.js).

Click here to view a screenshot of the full table 🙂

Resource / SDK VPC Internet Gateway NAT Gateway Security Group My Suggestion
Describe command DescribeVpcsCommand DescribeInternetGatewaysCommand DescribeNatGatewaysCommand DescribeSecurityGroupsCommand DescribeCommand
Describe command input {
“Filters”: [],
“VpcIds”: []
}
{
“Filters”: [],
“InternetGatewayIds”: []
}
{
“Filter”: [],
“NatGatewayIds”: []
}
{
“Filters”: [],
“GroupIds”: []
}
{
“Filters”: [],
“Ids”: []
}
Describe command output {
“Vpcs”: [
{
“VpcId”: “”,
“State”: “”,
“Tags”: []
}
]
}
{
“InternetGateways”: [
{
“InternetGatewayId”: “”,
“Attachments”: [
{
“State”: “”
}
],
“Tags”: []
}
]
}
{
“NatGateways”: [
{
“NatGatewayId”: “”,
“State”: “”,
“Tags”: []
}
]
}
{
“SecurityGroups”: [
{
“GroupId”: “”,
State”: “”,
“Tags”: []
}
]
}
{
“Items”: [
{
“Id”: “”,
“State”: “”,
“Tags”: []
}
]
}
Create command CreateVpcCommand CreateInternetGatewayCommand CreateNatGatewayCommand CreateSecurityGroupCommand CreateCommand
Create command input {
“TagSpecifications”: [
{
“ResourceType”: “vpc”,
“Tags”: []
}
]
}
{
“TagSpecifications”: [
{
“ResourceType”: “internet-gateway”,
“Tags”: []
}
]
}
{
“TagSpecifications”: [
{
“ResourceType”: “natgateway”,
“Tags”: []
}
]
}
{
“TagSpecifications”: [
{
“ResourceType”: “security-group”,
“Tags”: []
}
]
}
{
“TagSpecifications”: [
{
“ResourceType”: “resource-type”,
“Tags”: []
}
]
}
Create command output {
“Vpc”: {
“VpcId”: “”,
“State”: “”,
“Tags”: []
}
}
{
“InternetGateway”: {
“InternetGatewayId”: “”,
“Attachments”: [
{
“State”: “”
}
],
“Tags”: []
}
}
{
“NatGateway”: {
“NatGatewayId”: “”,
“State”: “”,
“Tags”: []
}
}
{
“SecurityGroup”: {
“GroupId”: “”,
“State”: “”,
“Tags”: []
}
}
{
“Item”: {
“Id”: “”,
“State”: “”,
“Tags”: []
}
}
Delete command DeleteVpcCommand DeleteInternetGatewayCommand DeleteNatGatewayCommand DeleteSecurityGroupCommand DeleteCommand
Delete command input {
“VpcId”: “”
}
{
“InternetGatewayId”: “”
}
{
“NatGatewayId”: “”
}
{
“GroupId”: “”
}
{
“Id”: “”
}
Delete command output {
“$metadata”: {}
}
{
“$metadata”: {}
}
{
“$metadata”: {},
“NatGatewayId”: “”
}
{
“$metadata”: {}
}
{
“$metadata”: {},
“Id”: “”
}