Serverless API with Deno and Begin - Part 1
Tags: deno, serverless, cloudnative, cloud
Published: 2021-01-06 19:34:06

[Deno](https://deno.land) is a runtime that can execute both JavaScript and TypeScript, which offers a very different development experience. Deno allows developers to write cloud functions with TypeScript without an explicit compile step or build tools.

Today we are going to deploy Deno as a serverless function with [Begin](https://begin.com). Along the way, we'll set up local development, describe how Deno is a little different from Node, and finally build an API endpoint that returns quotes from the famous actor, Nicolas Cage. 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3b0890scyiw2yqfhatsu.jpg)

## Prerequisites 
You can install Deno in a few different ways. I chose to install it with `brew install deno`, but you can [check their docs](https://github.com/denoland/deno_install) for other methods. 

You will also need Node, Git, and a Github account.

## Try out a Deno Hello World example right now
Hit this button to deploy a new `Hello World!` Deno app to Begin in 15 seconds (no credit card required):

[![Deploy to Begin](https://static.begin.com/deploy-to-begin.svg)](https://begin.com/apps/create?template=https://github.com/begin-examples/deno-hello-world)

## Setting up local development
Begin creates a GitHub repo for your app. Go ahead and clone the repo and install dependencies. 

```bash
git clone https://github.com/github-username/your-app.git
cd your-app
npm install
```

We can then start Sandbox with an npm script. Sandbox is a local development server that exposes our functions to HTTP routes, just like API Gateway. It can also emulate DynamoDB, SNS events, and SQS queues. 

```bash
npm start
```

Once you get your local environment running, we can now start modifying the `get-index` function. 

```javascript
// src/http/get-index/index.ts
let quote = function() {
  let min = 0
  let max = quotes.length - 1
  let rando = ~~(Math.random() * (max-min) + min)
  return quotes[rando]
}
let quotes = [
"It's a family that's loaded with grudges and passion. We come from a long line of robbers and highwaymen in Italy, you know. Killers, even.",
"To be a good actor you have to be something like a criminal, to be willing to break the rules to strive for something new.",
"I think I jump around more when I'm alone.",
"I bought a Yamaha-1 and I was doing 180 miles per hour home on the 405 and that's really, really crazy but I did it.",
"I believe that being successful means having a balance of success stories across the many areas of your life. You can't truly be considered successful in your business life if your home life is in shambles."
]
export async function handler (req: object) {
  return {
    statusCode: 200,
    headers: {
     'content-type': 'text/html; charset=utf8',
     'cache-control': 'no-cache, no-store, must-revalidate, max-age=0, s-maxage=0'
    },
    body:`
    <!doctype html>
    <html lang=en>
    <head>
    <meta charset=utf-8>
    <title>Hi!</title>
    <link rel="stylesheet" href="https://static.begin.app/starter/default.css">
    <link href="data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=" rel="icon" type="image/x-icon">
    </head>
    <body><h1 class="center-text">Praise Cage</h1>
    <p class="center-text"><q>${quote()}</q></p>
    <div class="center-text"><img src="https://www.placecage.com/g/300/300"></div>
    <p class="center-text">Your <a href="https://begin.com" class="link" target="_blank">Begin</a> app is ready to go!</p
    </body>
    </html>`
   }
}
```
`quote()` is a function. that returns a single random item from the `quotes` array. The `handler()` function executes each time a user requests the index route of your app. Its job is to call `quote()` and return an HTTP response with headers and an HTML string in the body.

Behind the scenes, you are working with an AWS Lambda function. Lambda functions are an event-driven, and stateless compute service. It has near-infinite scaling and doesn't requires traditional HTTP server configurations. The `app.arc` file in the root of your project defines all the routes under the `@http` pragma. [Check out the docs for more info on project structure](https://docs.begin.com/en/getting-started/project-structure).

Using Deno as a custom Lambda runtime layer, we were able to write Typescript.

## Look at what we have so far 
Refresh http://localhost:3333 and check out your results! You can replace the `quotes` array with a different list of items, but I think Nicolas Cage is the best choice. #praisecage
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/wwxnh0qqy5o3s9whjzai.png)
 
## Deploy with CI/CD on Begin
Such a beautiful site deserves a good home on the web. Deploying this app is just one `git push` away. Every push to your default branch will start a new deployment to `staging`. Go ahead and show it off by sharing it with us on [Twitter](https://www.twitter.com/begin).

## //todo: add API route
In the next post, we'll add a dedicated API route for other applications to take advantage of our quote machine. So stay tuned!