The Secret Life of AWS: The Serverless Coding Mindset
Stop writing code for servers. How to shift your mindset from "Linux Heavy" to "Serverless Lite".
Part 22 of The Secret Life of AWS
Timothy was typing furiously. He was building a Lambda function to process the "Order Events" from Episode 20.
Margaret stopped by to review the code. She raised an eyebrow. The file was 400 lines long.
"Timothy," she asked gently. "What is all this?"
"It is robust code," Timothy said proudly. "Look here: I created a ThreadPool to handle multiple records. Then I added a RetryLoop with exponential backoff in case the database is busy. And here, I am managing a connection pool to the database."
"So...you are writing code for a Server," Margaret said. "But there is no server."
"You are treating AWS Lambda like a tiny Linux box," she said quietly. "You are trying to manage concurrency, retries, and sockets inside your code. In the serverless world, that is not our job. That is Amazon's job."
"You are writing Heavy Code," she said. "We need to write Serverless Code."
The Heavy Function
Margaret pointed to the ThreadPool.
"Please tell me: why are you managing threads?"
"To process the batch of records faster," Timothy said.
"If you need more speed, you don't add threads," Margaret explained. "You decrease the Batch Size on the trigger. If SQS sends you 100 messages, don't write a loop to process them in parallel. Tell SQS to send you 10 batches of 10. Let AWS spin up 10 Lambda functions."
"You trade Code Complexity for Cloud Concurrency," she summarized.
The Retry Loop
Next, Margaret pointed to the complex while loop with the backoff logic.
"Tell me why this is here."
"In case the DynamoDB connection fails," Timothy said. "I want to try again."
"Let's remove that," Margaret suggested gently. "In serverless, we let the infrastructure handle retries.
Timothy gasped. "But if it fails, the data is lost!"
"Don't worry," Margaret said. "If your function throws an error, the Lambda Service catches it. It will automatically retry the event based on the policy we configured (Episode 19). If it fails 3 times, the Infrastructure moves it to the Dead Letter Queue."
"Think of your function as a pure mathematical transformation," she added. "Input comes in; Output goes out. If it can't transform, fail fast. Don't be defensive; be Binary. Let the architecture handle the recovery."
The Connection Pool
She pointed to the complex database connection logic.
"And here? It looks like you are manually managing keep-alives."
"I don't want to reconnect every time," Timothy said.
"Let's initialize the client outside the handler," Margaret advised. "But we won't write a complex pool manager. If we need connection pooling for a relational database, we'll use Amazon RDS Proxy. We won't bother your function with infrastructure management."
The Refactor
Margaret sat down at the keyboard. "Let's refactor."
She deleted the thread pool.
She deleted the retry loop.
She deleted the custom logging logic.
The 400-line file shrank to 25 lines.
def handler(event, context):
# 1. Parse Input
order_id = event['detail']['orderId']
# 2. Business Logic
db.save_order(order_id)
marketing.add_points(order_id)
# 3. Done
return {"status": "success"}
"It looks... naked," Timothy said. "It’s just business logic."
"Exactly," Margaret smiled. "And because it is smaller, it loads faster. This helps avoid Cold Starts."
"In a serverless environment," she concluded, "your code is just the Connector between services. It doesn't need to be strong, because the platform is strong. It just needs to be correct."
Aaron Rose is a software engineer and technology writer at tech-reader.blog and the author of Think Like a Genius.


Comments
Post a Comment