How to use external APIs with Serverless Functions
Tags: cloudnative, aws, javascript, serverless
Published: 2021-03-24 15:16:29

Working with an external API is a very common use case. In this post we will be using a Lambda function to make a data call to the [Open Movie Database](https://www.omdbapi.com/) to get a list of Nicolas Cage movies and some information. 

# Create a new Architect project
The first step is starting a new Architect project from the command line 

```bash
npm init @architect ./cage-characters
cd cage-characters
npm install @architect/functions tiny-json-http
```
# Infrastructure as Code 
Let's take a look at the `app.arc` file. This file is our infrastructure as code manifest. It lives in the root of our project and tells Architect where the code lives and how to deploy it. 
 
```
@app
cage-characters

@http
get /
```
In this example, we're only using a single route. So let's modify the `get-index` function. But first, we need to get an API key from the Open Movie Database. Grab one by going to [http://www.omdbapi.com/apikey.aspx](http://www.omdbapi.com/apikey.aspx) and they will email you an API key to include in the request.

# Set up environment variables

We're going to set up a `prefs.arc` file to use as an environment variable so we don't commit this secret to GitHub.

Create a `prefs.arc` file in the root of your project.

```
# prefs.arc

@env
testing
  MOVIE_API_KEY your-api-key-here
```
When we deploy this app, we will set environment variables in the Begin console. 

Now we can start to modify the `get-index` handler with our logic to query the movie database and display the information in the browser. 

```javascript
// src/http/get-index/index.js

let arc = require('@architect/functions')
let tiny = require('tiny-json-http')

async function route(req) {
  let url = `https://api.themoviedb.org/3/person/2963/movie_credits?api_key=${process.env.MOVIE_API_KEY}`
  let imageUrl = 'http://image.tmdb.org/t/p/w500/'
  let result = await tiny.get({url})
  let movies = result.body.cast

  let html = movies.map(movie => `<h3>${movie.character} - ${movie.original_title}</h3> <p>${movie.overview}</p> <img src=${imageUrl + movie.backdrop_path}></img>`).join('')

  return {
    statusCode: 200,
    html: html
  }
}

exports.handler = arc.http.async(route)
```
This function returns a string back to the browser to render as HTML. You can now run `npm start` to kick off the local development server and look at the results at http://localhost:3333. 

# Depoloying on Begin
The final step is to deploy this application on Begin. Begin is the easiest way to deploy your Architect projects to live AWS infrastructure. To do this, create a free Begin account by going to https://begin.com and using your GitHub account to log in. Create a new app and associate it with this repo. Begin will then create hooks to your repo and deploy the app to a staging environment on every `git push`. 

You can see the full code example here: [https://github.com/pchinjr/cage-characters](https://github.com/pchinjr/cage-characters)

You can find the full documentation for the Open Movie Database here: [https://developers.themoviedb.org/3/getting-started/introduction](https://developers.themoviedb.org/3/getting-started/introduction)