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? Wasn’t 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. Every developer on the team (not just the team lead or senior developers) 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).

And yes, this applies to microservices as well – imagine 1000 different JSON structures, naming conventions and authentication request headers for the requests and responses of 1000 microservices in an organization’s public API ๐Ÿ˜›

Click here to view a screenshot of the full table ๐Ÿ™‚

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