惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Heimdal Security Blog
小众软件
小众软件
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
罗磊的独立博客
Google DeepMind News
Google DeepMind News
大猫的无限游戏
大猫的无限游戏
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Hugging Face - Blog
Hugging Face - Blog
阮一峰的网络日志
阮一峰的网络日志
A
About on SuperTechFans
宝玉的分享
宝玉的分享
博客园 - 聂微东
月光博客
月光博客
Cyberwarzone
Cyberwarzone
Microsoft Security Blog
Microsoft Security Blog
V
Visual Studio Blog
Project Zero
Project Zero
T
Tor Project blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
L
LINUX DO - 最新话题
博客园 - 叶小钗
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Attack and Defense Labs
Attack and Defense Labs
Spread Privacy
Spread Privacy
Forbes - Security
Forbes - Security
Simon Willison's Weblog
Simon Willison's Weblog
N
Netflix TechBlog - Medium
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
Hacker News: Ask HN
Hacker News: Ask HN
I
InfoQ
M
MIT News - Artificial intelligence
AI
AI
博客园 - 三生石上(FineUI控件)
W
WeLiveSecurity
C
Check Point Blog
The Hacker News
The Hacker News
C
Cyber Attacks, Cyber Crime and Cyber Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
T
Tenable Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
The Cloudflare Blog
Blog — PlanetScale
Blog — PlanetScale
美团技术团队
D
Darknet – Hacking Tools, Hacker News & Cyber Security
GbyAI
GbyAI
Hacker News - Newest:
Hacker News - Newest: "LLM"
腾讯CDC
K
Kaspersky official blog

Blog — PlanetScale

Keeping a Postgres queue healthy — PlanetScale Patterns for Postgres Traffic Control — PlanetScale Graceful degradation in Postgres — PlanetScale High memory usage in Postgres is good, actually — PlanetScale Stripe Projects partnership: Provision PlanetScale Postgres and MySQL databases from the Stripe CLI — PlanetScale Enhanced tagging in Postgres Query Insights — PlanetScale Behind the scenes: How Database Traffic Control works — PlanetScale Introducing Database Traffic Control — PlanetScale Scaling Postgres connections with PgBouncer — PlanetScale Drizzle joins PlanetScale — PlanetScale Video Conferencing with Postgres — PlanetScale Faster PlanetScale Postgres connections with Cloudflare Hyperdrive — PlanetScale Introducing the PlanetScale MCP server — PlanetScale Database Transactions — PlanetScale Automating our changelog with Cursor commands — PlanetScale Postgres 18 is now available — PlanetScale Using MotherDuck with PlanetScale — PlanetScale $50 PlanetScale Metal is GA for Postgres — PlanetScale AI-Powered Postgres index suggestions — PlanetScale $5 PlanetScale is live — PlanetScale Announcing Vitess 23 — PlanetScale $50 PlanetScale Metal — PlanetScale Report on our investigation of the 2025-10-20 incident in AWS us-east-1 — PlanetScale $5 PlanetScale — PlanetScale Benchmarking Postgres 17 vs 18 — PlanetScale Larger than RAM Vector Indexes for Relational Databases — PlanetScale Partnering with Cloudflare to bring you the fastest globally distributed applications — PlanetScale Processes and Threads — PlanetScale PlanetScale for Postgres is now GA — PlanetScale Postgres High Availability with CDC — PlanetScale Announcing Neki — PlanetScale Caching — PlanetScale The principles of extreme fault tolerance — PlanetScale Announcing PlanetScale for Postgres — PlanetScale Benchmarking Postgres — PlanetScale Announcing Vitess 22 — PlanetScale The Real Failure Rate of EBS — PlanetScale IO devices and latency — PlanetScale Announcing PlanetScale Metal — PlanetScale PlanetScale Metal: There’s no replacement for displacement — PlanetScale Upgrading Query Insights to Metal — PlanetScale Automating cherry-picks between OSS and private forks — PlanetScale Database Sharding — PlanetScale Anatomy of a Throttler, part 3 — PlanetScale Introducing sharding on PlanetScale with workflows — PlanetScale Announcing Vitess 21 — PlanetScale Announcing the PlanetScale vectors public beta — PlanetScale Anatomy of a Throttler, part 2 — PlanetScale Instant deploy requests — PlanetScale Anatomy of a Throttler, part 1 — PlanetScale Increase IOPS and throughput with sharding — PlanetScale Tracking index usage with Insights — PlanetScale Faster backups with sharding — PlanetScale Building data pipelines with Vitess — PlanetScale The State of Online Schema Migrations in MySQL — PlanetScale Optimizing aggregation in the Vitess query planner — PlanetScale Dealing with large tables — PlanetScale Announcing Vitess 20 — PlanetScale Self-managed Vitess vs Managed Vitess with PlanetScale — PlanetScale Achieving data consistency with the consistent lookup Vindex — PlanetScale The MySQL adaptive hash index — PlanetScale Introducing global replica credentials — PlanetScale Profiling memory usage in MySQL — PlanetScale Summer 2023: Fuzzing Vitess at PlanetScale — PlanetScale How PlanetScale makes schema changes — PlanetScale Identifying and profiling problematic MySQL queries — PlanetScale The Problem with Using a UUID Primary Key in MySQL — PlanetScale Announcing Vitess 19 — PlanetScale PlanetScale forever — PlanetScale Introducing schema recommendations — PlanetScale Amazon Aurora Pricing: The many surprising costs of running an Aurora database — PlanetScale Three common MySQL database design mistakes — PlanetScale OAuth applications are now available to everyone — PlanetScale Deprecating the Scaler plan — PlanetScale PlanetScale branching vs. Amazon Aurora blue/green deployments — PlanetScale Databases at scale — PlanetScale Considerations for building a database disaster recovery plan — PlanetScale Working with Geospatial Features in MySQL — PlanetScale PlanetScale vs Amazon Aurora replication — PlanetScale Introducing the Vantage and PlanetScale integration — PlanetScale MySQL isolation levels and how they work — PlanetScale Introducing the schemadiff command line tool — PlanetScale $ pscale ping — PlanetScale Announcing foreign key constraints support — PlanetScale The challenges of supporting foreign key constraints — PlanetScale What is HTAP? — PlanetScale Introducing Insights Anomalies — PlanetScale Webhook security: a hands-on guide — PlanetScale MySQL replication: Best practices and considerations — PlanetScale A guide to HTML email with Ruby on Rails and Tailwind CSS — PlanetScale Sharding for cost-effective database management — PlanetScale PlanetScale ranks 188th in Deloitte’s top 500 fastest-growing companies — PlanetScale Announcing the Fivetran integration — PlanetScale Introducing webhooks — PlanetScale What is MySQL replication and when should you use it? — PlanetScale Sync user data between Clerk and a PlanetScale MySQL database — PlanetScale Introducing database reports — PlanetScale Distributed caching systems and MySQL — PlanetScale What is MySQL partitioning? — PlanetScale MySQL High Availability: Connection handling and concurrency — PlanetScale
Using the PlanetScale serverless driver with AWS Lambda functions — PlanetScale
Brian Morrison II · 2022-09-21 · via Blog — PlanetScale

Brian Morrison II |

Overview

We recently released the PlanetScale serverless driver for JavaScript to allow developers to connect to their databases over HTTP, as opposed to TCP, which is blocked by some cloud providers. This guide will walk you through the most common use cases of the driver while building a serverless API on AWS using a Lambda function and API Gateway.

To follow along, you’ll need:

Warning

Please note that building on top of AWS costs real money. Some of the costs may be covered on the AWS free tier.

Set up the database on PlanetScale

Start in PlanetScale by creating a new database. I’ll name mine travel_api.

The New database modal in PlanetScale.

Now let’s add some data. Click on "Branches" > "main" to access the main branch.

The Branches tab of the database.

Now click on "Console" to access the web console of the main branch.

The Console tab of the main branch.

Run the following two SQL snippets to create a table and add a few records to it.

CREATE TABLE hotels(
  id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(50) NOT NULL,
  address VARCHAR(50) NOT NULL,
  stars FLOAT(2) UNSIGNED
);
INSERT INTO hotels (name, address, stars) VALUES
  ('Hotel California', '1967 Can Never Leave Ln, San Francisco CA, 94016', 7.6),
  ('The Galt House', '140 N Fourth St, Louisville, KY 40202', 8.0);

The serverless driver is currently in beta and needs to be enabled on the database level. To do this, click on the "Settings" tab > "Beta features", and click "Enroll" next to the PlanetScale serverless driver for JavaScript line. By enabling this feature, every new password created will have a different hostname, specifically to endpoints that support accessing your database over HTTP.

The location of the enroll button for the driver.

Now head back to the "Overview" tab and click "Connect".

The Overview tab of the database.

From the Connect modal, select "@planetscale/database" from the dropdown. Note the text in the .env tab as we’ll need to configure these as environment variables in AWS.

The Connect modal.

Set up the Lambda function

Start by creating an empty folder on your computer and opening VS Code. Open the integrated terminal and run the following command to initialize the project & install the necessary packages:

npm init -y
npm install @planetscale/database node-fetch

Open the package.json file and add a new entry to the file named “type” and give it a value of “module”.

{
  "name": "serverless-driver-aws-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module", # ◀️ add type here
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@planetscale/database": "^1.3.0",
    "node-fetch": "^3.2.10"
  }
}

Create a file called index.js and add the following code to it.

import { Client } from '@planetscale/database'
import fetch from 'node-fetch'

const db = new Client({
  fetch,
  host: process.env.DATABASE_HOST,
  username: process.env.DATABASE_USERNAME,
  password: process.env.DATABASE_PASSWORD
})

export async function handler(event) {
  const conn = db.connection()
  const results = await conn.execute('SELECT * FROM hotels')
  console.log(results)
}

Now we need to get the code into an AWS Lambda function. Log into the AWS console, search for “Lambda”, and select it from the list.

Lambda in the AWS search box.

Click "Create function".

The AWS Lambda landing page.

Give the function a name and make sure "Node.js 16.x" is selected under Runtime.

The Create function screen.

Once the function has been created, we need to upload a zipped version of the code we wrote. Zip up the contents of the folder, then in AWS, select "Upload from" > ".zip file".

The location of the .zip file upload option.

Click the "Upload" button from the modal, select the zipped folder you created, and click "Save".

The Upload modal in AWS.

Next, select "Configuration" > "Environment variables", and click "Edit" in the main section of the window to add environment variables.

The Environment variables section of Lambda.

Click "Add environment variable" three times to get three entries and populate the fields using the environment variables gathered from the Connect modal in PlanetScale. Click "Save" once you’ve added them.

The Edit environment variables screen in AWS.

Now head back to the "Code" tab and click "Test".

The location of the Test button in Lambda.

A modal will appear called Configure test event. Populate the "Event name" field with any arbitrary string (I’ll use “Test”), scroll to the bottom, and click "Save".

The Configure test event modal.

Now click "Test" again and it will run the function. You should see the output of the results object in a tab of the editor.

The output of the test in AWS.

Build an API with API Gateway

Now that you’ve seen how to use the serverless driver for JavaScript in the code, let’s explore the other common query types by re-building the function to support API Gateway, and mapping some of the HTTP methods to those queries like so:

HTTP Method NameQuery Type
getSELECT
postINSERT
putUPDATE
deleteDELETE

In the following code sample, we’ve pulled out the logic to run the SELECT statement from the previous section into the get() function. We’re also using a switch statement on event.requestContext.http.method to map the request to a different function depending on that HTTP method. Finally, we also added a method to handle a post request so we can add data to the database.

Update index.js to match the following code, zip up the contents once again, and upload them into Lambda using the process defined earlier:

import { Client } from '@planetscale/database'
import fetch from 'node-fetch'

const db = new Client({
  fetch,
  host: process.env.DATABASE_HOST,
  username: process.env.DATABASE_USERNAME,
  password: process.env.DATABASE_PASSWORD
})

export async function handler(event) {
  const conn = db.connection()

  switch (event.requestContext.http.method) {
    case 'GET':
      return await get(conn, event)
    case 'POST':
      return await post(conn, event)
    default:
      return {
        statusCode: 404
      }
  }
}
async function get(conn, event) {
  const results = await conn.execute('SELECT * FROM hotels')

  return {
    statusCode: 200,
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(results.rows)
  }
}

async function post(conn, event) {
  const { name, address, stars } = JSON.parse(event.body)

  const res = await conn.execute('INSERT INTO hotels (name, address, stars) VALUES (:name, :address, :stars)', {
    name,
    address,
    stars
  })

  if (res.error) {
    return {
      statusCode: 500,
      headers: {
        'Content-Type': 'application/javascript'
      },
      body: JSON.stringify(res.error)
    }
  }

  return {
    statusCode: 200,
    headers: {
      'Content-Type': 'application/javascript'
    },
    body: JSON.stringify({
      id: Number(res.insertId)
    })
  }
}

Now head into the AWS console and find “API Gateway” using the global search.

API Gateway in the AWS search.

Click on "Create API" to start the process of building a new instance of API Gateway for the Lambda function we created.

The Create API button in API Gateway.

To create an HTTP API, click the "Build" button in that section.

The Choose an API type step of the Create API process.

Click on "Add integration". Then select Lambda as the integration type, and select the Lambda you created in the previous section. Give your API a name as well and click "Next".

The first step of the Create API process.

Under Configure routes, change the Resource path to be /hotels and click "Next".

The Configure routes step of the Create API process.

Nothing needs to be changed in the Define stages step, so click "Next".

The Define stages step of the Create API process.

Finally, click "Create" to complete the process.

The Review and create step of the Create API process.

Now grab the Invoke URL from the API you just created, we’ll use this to build some simple tests within VS Code.

The location of the Invoke URL in API Gateway.

Back in VS Code, create a new file in the root of your directory called tests.http and populate it with the following. Make sure to replace <YOUR_INVOKE_URL> with what you pulled from API Gateway.

@hostname = <YOUR_INVOKE_URL>

### Fetch hotels
get {{hostname}}/hotels

### Create hotel
post {{hostname}}/hotels
Content-Type: application/json
{
  "name": "Orka Sunlife Resort",
  "address": "Güzgülü Mevkii, Ölüdeniz Cd.",
  "stars": 4.2
}

The VS Code Rest Client plugin should recognize this file and display a small link with "Send Request" above each defined request method.

The location of Send Request for each HTTP test.

Click the "Send Request" link above the get method and you should receive an array of hotels in a second window pane that will be created automatically.

The output of the get method.

Now test the post method by clicking "Send Request" above that one. You should receive an id field to reflect the ID of the inserted record in PlanetScale.

The output of the post method.

Optionally you can also check the database in PlanetScale using the console to run the following script:

This should display the newly created hotel along with the original two added earlier.

The hotels table in the PlanetScale console.

Now let’s get the put and delete methods working. Update the handler function in the code to reflect the following. Note that the switch statement has been updated to handle those methods.

export async function handler(event) {
  const conn = db.connection()

  switch (event.requestContext.http.method) {
    case 'GET':
      return await get(conn, event)
    case 'POST':
      return await post(conn, event)
    case 'PUT':
      return await put(conn, event)
    case 'DELETE':
      return await del(conn, event)
    default:
      return {
        statusCode: 404
      }
  }
}

At the end of the file, add the put and del JavaScript methods (we have to use del since delete is a keyword in the JavaScript language). Zip and re-upload the code into AWS after this has been done.

async function put(conn, event) {
  const { id } = event.pathParameters
  const { name, address, stars } = JSON.parse(event.body)

  const res = await conn.execute('UPDATE hotels SET name=:name, address=:address, stars=:stars WHERE id=:id', {
    name,
    address,
    stars,
    id
  })

  if (res.error) {
    return {
      statusCode: 500,
      headers: {
        'Content-Type': 'application/javascript'
      },
      body: JSON.stringify(res.error)
    }
  }

  return {
    statusCode: 200
  }
}

async function del(conn, event) {
  const { id } = event.pathParameters

  const res = await conn.execute('DELETE FROM hotels WHERE id=:id', {
    id
  })

  if (res.error) {
    return {
      statusCode: 500,
      headers: {
        'Content-Type': 'application/javascript'
      },
      body: JSON.stringify(res.error)
    }
  }

  return {
    statusCode: 200
  }
}

Since typically put and delete methods are used on individual records, they are often accompanied by a record ID in the URL. We need to add an API route in API Gateway to handle the URL pattern /hotels/{id}. Navigate to your API in API Gateway again, select "Routes" from the left nav, and click "Create".

The Routes section of API Gateway.

In the route field, add "/hotels/{id}" and click "Create".

The Create a route screen in API Gateway.

Select the new route from the list and click "Attach integration".

The Route details section of the new route in API Gateway.

Select your Lambda function from the list and click "Attach integration" again.

Adding an integration to the route.

Now head back to the tests.http file in VS Code and add the following two requests to the file. Notice the JSON under the put request has each field modified just a bit. An ID of 3 is also at the end of the URL, which is how the Lambda code identifies which record it should update.

### Update hotel
put {{hostname}}/hotels/3
Content-Type: application/json
{
  "name": "Orka Sunlife Resort Aqua",
  "address": "Güzgülü Mevkii, Ölüdeniz Cd. Turkey",
  "stars": 4.3
}
### Delete hotel
delete {{hostname}}/hotels/3

Run the put request and it simply returns an OK status, but if you run the get request again, you’ll see that the third entry in the array reflects the updated values we sent int.

Output of the get request after hotel 3 has been updated.

Finally, run the delete request. Again, it returns an OK status. Run the get again and that third record is removed.

Output of the get request after hotel 3 has been deleted.

For more information on how to use the PlanetScale serverless driver for JavaScript, refer to our documentation portal where we have a detailed overview of when you should use it, as well as an example built with Node and Express that you can run directly on your workstation.