Creating Serverless MySQL HTTP (SMH) as an Emulation Service for PlanetScale
Tags: database, mysql, serverless, opensource
Published: 2023-11-27 11:25:24

## Introduction

I decided to try out a serverless MySQL service called [PlanetScale](https://planetscale.com/). However, it seemed that PlanetScale didn't have a local development environment emulation service, similar to AWS's [LocalStack](https://www.localstack.cloud/) or Firebase's [Firebase Local Emulator Suite](https://firebase.google.com/docs/emulator-suite).

So, I thought, if it doesn't exist, why not create it? In this article, I'd like to share about Serverless MySQL HTTP (SMH), which I developed for this purpose.

https://github.com/yutak23/serverless-mysql-http

## What is PlanetScale?

https://planetscale.com/

> PlanetScale is a MySQL-compatible serverless database that brings you scale, performance, and reliability — without sacrificing developer experience. With PlanetScale, you get the power of horizontal sharding, non-blocking schema changes, and many more powerful database features without the pain of implementing them.



## About Serverless MySQL HTTP (SMH) Created This Time

With PlanetScale, you can send requests and manage the database via HTTP using the [@planetscale/database](https://github.com/planetscale/database-js) library. 

Using the @planetscale/database library allows for the use of PlanetScale even in edge environments. However, this approach has a downside: it doesn't support the usual development methods used with MySQL. Typically, for apps using MySQL, development is done locally with a MySQL server set up, say, in Docker, without connecting to the production MySQL environment[^1]. However, when using [@planetscale/database](https://github.com/planetscale/database-js), requests sent over HTTP to PlanetScale do not work with a local MySQL environment due to protocol differences (as shown in the image below).
[^1]: For example, AWS RDS or Aurora, Azure's Azure Database for MySQL, GCP's Cloud SQL for MySQL, etc.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0wy9wuc36np6xvmtjqvt.png)

Hence, a service is needed that can translate (or proxy) HTTP requests into MySQL protocol. This is where Serverless MySQL HTTP (SMH) comes into play.

Using this service, as shown in the following image, HTTP requests to PlanetScale are received by SMH, which then converts them into MySQL protocol. This allows for development using a local MySQL environment even when using [@planetscale/database](https://github.com/planetscale/database-js).

![Image showing how SMH works](https://storage.googleapis.com/zenn-user-upload/ee6f8caf88dd-20231127.png)

Serverless MySQL HTTP (SMH) is available as a Docker image.

https://hub.docker.com/r/yutak23/serverless-mysql-http

*Note: As mentioned above, SMH is specifically designed for use with the [PlanetScale serverless driver for JavaScript](https://planetscale.com/docs/tutorials/planetscale-serverless-driver).*

## Mechanism and Key Points
### Mechanism

The mechanism is quite simple: SMH is implemented as a Node.js Express server that receives HTTP requests. It uses [node-mysql2](https://github.com/sidorares/node-mysql2) to query MySQL. The HTTP response needs to be converted into a format required by [@planetscale/database](https://github.com/planetscale/database-js), which was a key point in the implementation.

### Key Points

PlanetScale is not a complete MySQL[^2], and the types differ slightly. I implemented a process to convert MySQL types to Vitess types for this.
[^2]: Vitess ([PlanetScale Vitess page](https://planetscale.com/vitess))

Also, in [@planetscale/database](https://github.com/planetscale/database-js), the HTTP request and response bodies appear to be Base64 encoded, so handling this was another key point.

## Conclusion

I introduced the development of Serverless MySQL HTTP (SMH), a service that allows for development in a local environment without connecting to the production service when using PlanetScale. I believe there's a need to develop without connecting to production services (otherwise, LocalStack and Firebase Local Emulator Suite wouldn't have been developed), so I hope that Serverless MySQL HTTP (SMH) will be helpful to someone.

[^1]: For example, AWS RDS or Aurora, Azure's Azure Database for MySQL, GCP's Cloud SQL for MySQL, etc.
[^2]: Vitess (https://planetscale.com/vitess)