Cree Un Bot De Discord Con AWS Lambda + API Gateway

Recientemente, Discord introdujo interacciones y comandos de barra para facilitar la experiencia de los usuarios con los bots. En parte, el motivo era proteger la privacidad de los usuarios: los bots ahora se ven ligeramente obligados a abandonar las banderas para leer mensajes en los servidores de Discord, lo que anteriormente era un motivo de preocupación con respecto al procesamiento ilegal de datos por parte de los desarrolladores de bots.

Estas son las funciones más conocidas, pero además de eso, la actualización ha agregado la posibilidad de interactuar con las interacciones mencionadas a través de la URL del punto final de interacciones.

Campo del panel del desarrollador para URL de extremo de interacciones.

Esto nos permite pasar de una aplicación de escucha tradicional alojada en un servidor a una aplicación sin servidor *aplausos* , que ejecuta una función Lambda en cada invocación de interacción.

Conexión de AWS Lambda a Discord

Durante la codificación, saltaremos entre "AWS", "Código" y "Portal de desarrolladores de Discord".

AWS

Usaremos AWS API Gateway y AWS Lambda para nuestra tarea. Es un conjunto de herramientas básico para la arquitectura sin servidor en AWS. Las funciones se escribirán en Node.js.

  1. Cree una cuenta e inicie sesión en https://aws.amazon.com
  2. Vaya al servicio API Lambda utilizando la navegación de la barra superior
  3. Elija la sección "Funciones" en la barra lateral (si aún no se ha elegido)
  4. Haga clic en "Crear función"

Página principal de AWS Lambda.

If you were brave enough to click it right away with plugged in credit card — you’ve probably used AWS or AWS Lambda before.

If you hesitated — it’s a moment to calm you down: The AWS Lambda free tier includes one million free requests per month and 400,000 GB-seconds of compute time per month. Way more than you will need for sake of this tutorial and probably ever after (though I wish you exceeding the limit!).

5. Choose your Function name, pick Node.js 14.x and Click “Create function”

Create function panel.

After creation, you should see the dashboard below.

Initial Lambda dashboard. Yeah, we will be clicking like that. Not a point in time to implement IaC.

Great! We have our lambda with a boilerplate code. Now add an API Trigger — we need some URI to pass to Discord Portal, right?

Trigger configuration.

Enable CORS to allow Discord’s host origin. Some day in the future, you may want to change the openness of API endpoint and CORS allowed domains so that you do not get bot-spammed (it’s not common for AWS resources though).

The result:

Trigger created.

Go to the API endpoint by clicking on its URL: you should see “Hello from Lambda!”

Code

Create project directory serverless_discord/. Inside, create a subdirectory lambda_bot/ and index.js within. Use the following code:

const nacl = require('tweetnacl');

exports.handler = async (event) => {
  // Checking signature (requirement 1.)
  // Your public key can be found on your application in the Developer Portal
  const PUBLIC_KEY = process.env.PUBLIC_KEY;
  const signature = event.headers['x-signature-ed25519']
  const timestamp = event.headers['x-signature-timestamp'];
  const strBody = event.body; // should be string, for successful sign

  const isVerified = nacl.sign.detached.verify(
    Buffer.from(timestamp + strBody),
    Buffer.from(signature, 'hex'),
    Buffer.from(PUBLIC_KEY, 'hex')
  );

  if (!isVerified) {
    return {
      statusCode: 401,
      body: JSON.stringify('invalid request signature'),
    };
  }


  // Replying to ping (requirement 2.)
  const body = JSON.parse(strBody)
  if (body.type == 1) {
    return {
      statusCode: 200,
      body: JSON.stringify({ "type": 1 }),
    }
  }
};

In the code above, we follow the structure that you can already see in AWS Lambda boilerplate code (exports.handler function).

Next, we fulfill endpoint requirements (payload verification and ping reply) set by Discord in the documentation. Verification is done with tweetnacl package, that we do not have yet. Let’s install it!

Best case would be if your node --version is close to the Lambda runtime’s version (we chose 14.x ) — ideally, if it’s the same. If it’s too far apart — along with npm — the packed modules may not work in Lambda.

npm i tweetnacl

Good. Now, let’s zip all of that (with node_modules!) and put back into our Lambda. While still being inside of your directory, type:

zip -r ../lambda_bot.zip *

AWS

Upload the zip in Lambda dashboard — section “Code”.

Lambda dashboard.

or through CLI instead, if you have AWS CLI installed and configured:

aws lambda update-function-code \
    --function-name discord \
    --zip-file fileb://../lambda_bot.zip

Everything looks great. Quick app creation at Discord in 3, 2, 1, go!

Discord Developer Portal

Go to Discord Developer Portal, choose New Application and pick a name. Copy previously created API endpoint to Interactions Endpoint URL field in bot’s configuration below.

My real AWS API Gateway URL.

and click Save!

Saving performs Discord-side check of their requirements — they send a set of POST requests to your endpoint.

Scroll to the top of the page for notification and — there you have it! Big Green Success bar — your Bot is live! You made it!

Huh? What? You’ve got some error? Umm, what’s the error message?

You sent me this unhelpful screenshot.

How can I fix the endpoint, when all I know is that “something” is wrong? At most, we may assume, that one of their two requirements is not fulfilled.

AWS

To debug it from AWS side, you can make some test snippets and run them against your code. Unfortunately, it’s not easy to find an exact call example from Discord to mock this.

You can also debug it quickly by running the code on your own computer (just strip the code in index.js from handler function), but you then you’d need external domain redirecting to your local IP, which has its own risks.

Let’s add console logs to have any idea, if the request is coming and if we interpret it correctly.

Add logging in very first lines of index.js

const nacl = require('tweetnacl');exports.handler = async (event) => {
  console.log(event)
  // Checking signature (requirement 1.)
  ...

and click “Deploy”.

In Discord Developer Portal, “Save” Discord Application settings (as a reminder — it will rerun Discord’s POST request to our Lambda). With the event (hopefully) logged, check it in CloudWatch.

Lambda dashboard — navigating to CloudWatch.

I found this error message:

Error message.

(the event itself was logged in one field higher, which may be helpful)

The error points to Line 15 in index.js , which states:

Buffer.from(PUBLIC_KEY, 'hex')

and points rightfully so. We did not pass PUBLIC_KEY environment variable, which is assigned to variable PUBLIC_KEY beforehand.

const PUBLIC_KEY = process.env.PUBLIC_KEY;

Get the Public Key of your app from Discord Developer Portal and insert in AWS Lambda’s: Configuration → Environment Variables → Edit… → Add… (do NOT use quotation marks for env variables)

Key: PUBLIC_KEY, Value: 55ff1c234...

Run “Save Changes” now!

All your edits have been carefully recorded.

Registering and creating Slash Commands

At the end of index.js , add handler for a command, that we will soon register.

I want a Slash Command /foo that replies “bar” (ok, not too mind-blowing).

const nacl = require('tweetnacl');

exports.handler = async (event) => {
  // Checking signature (requirement 1.)
  // Your public key can be found on your application in the Developer Portal
  const PUBLIC_KEY = process.env.PUBLIC_KEY;
  const signature = event.headers['x-signature-ed25519']
  const timestamp = event.headers['x-signature-timestamp'];
  const strBody = event.body; // should be string, for successful sign

  const isVerified = nacl.sign.detached.verify(
    Buffer.from(timestamp + strBody),
    Buffer.from(signature, 'hex'),
    Buffer.from(PUBLIC_KEY, 'hex')
  );

  if (!isVerified) {
    return {
      statusCode: 401,
      body: JSON.stringify('invalid request signature'),
    };
  }


  // Replying to ping (requirement 2.)
  const body = JSON.parse(strBody)
  if (body.type == 1) {
    return {
      statusCode: 200,
      body: JSON.stringify({ "type": 1 }),
    }
  }

  // Handle /foo Command
  if (body.data.name == 'foo') {
    return JSON.stringify({  // Note the absence of statusCode
      "type": 4,  // This type stands for answer with invocation shown
      "data": { "content": "bar" }
    })
  }


  return {
    statusCode: 404  // If no handler implemented for Discord's request
  }
};

Copy and paste the updated code to AWS Lambda code editor or zip it and upload it like the last time. Click “Deploy”.

Registering /foo command

Create a second subdirectory in serverless_discord/ , called register_commands/ , and navigate into it.

➜  serverless_discord mkdir register_commands && cd register_commands

Create a new file register.js with:

require('dotenv').config()
const axios = require('axios').default;

let url = `https://discord.com/api/v8/applications/${process.env.APP_ID}/guilds/${process.env.GUILD_ID}/commands`

const headers = {
  "Authorization": `Bot ${process.env.BOT_TOKEN}`,
  "Content-Type": "application/json"
}

let command_data = {
  "name": "foo",
  "type": 1,
  "description": "replies with bar ;/",
}

axios.post(url, JSON.stringify(command_data), {
  headers: headers,
})

To add missing modules, run:

npm i axios dotenv

But, why do we have two different packages (folders) now?

Well, this one will not be on AWS Lambda and does not have to be anywhere remote, actually. Ideally, registering commands, should happen during CI/CD Pipeline, when there are commands changes. Without CI/CD, it’s totally OK to run the script manually from your local PC after you develop something new.

Create .env file and change values to yours:

BOT_TOKEN=OTYxNzM2M123AB123AB123AB1231
APP_ID=9617363832323452345
GUILD_ID=838565977234523452

ForGUILD_ID, go to Discord App, create a Discord Guild (colloquially Discord Server). In your User Settings → Advanced → Developer Mode ON. Go back to main discord screen, right click on your Guild and click Copy ID.

Then, go to Discord Developer Portal, choose your app → Bot → Add Bot → Reset Token → Copy — it is your BOT_TOKEN.

Find APP_ID in General Information section.

Go to OAuth2 section → URL Generator. Choose Scopes: bot, application.commands. Bot permissions: Use Slash Commands.

Copy URL generated below and visit it — choose Guild, that you have just made.

Generated URL.

You are right, we limit the scope to just one guild (yours). Slash commands will NOT appear in other guilds, that you will invite bot into. When creating Slash Commands with Guild Scope, it applies changes immediately — that’s why it is always used in the development process until the bot is very ready. Creating or changing Global Commands is rolled out for each guild in 0–60 minutes.

Changing scope to Global later on, should take you around 5 minutes with the official documentation.

Enough talking, let’s deploy the command!

➜  register_commands node register.js
➜  register_commands

No error means success! Go quickly to your Discord Guild chat, start typing /foo and press Enter.

Drumroll…

BAR!

Congratulations! 🏆

Your serverless bot is now u̶p̶ ̶a̶n̶d̶ ̶r̶u̶n̶n̶i̶n̶g̶ waiting for events :)

Summary

Upsides:

  1. Low cost
  2. Easy to implement
  3. Very well scalable — no need for sharding (with only linear cost increase!)

Downsides:

  1. Locked to AWS (vendor-lock) (this particular solution)
  2. May require CI/CD implementation more than “serverful” options — otherwise, altering AWS resources may be tedious
  3. This architecture needs proper logging and debug messages on client and server-side in order to be effective.

In this article you have learned:

  1. Basic serverless toolkit on AWS
  2. The current state of Discord Bot programming
  3. Challenges with AWS Lambda — development, deployment, debugging
  4. Payload verification with nacl and making requests with axios

Additional sources:

Climb higher in my next article:

AWS SAM: configuración del desarrollo sin servidor local con Lambda y DynamoDB

Como dice su nueva función, ¡es hora de celebrar en el bar !

(Ahora la imagen de introducción del artículo no se siente tan extraña, ¿verdad?) 

Esta historia se publicó originalmente en https://betterprogramming.pub/build-a-discord-bot-with-aws-lambda-api-gateway-cc1cff750292

#lambda #api #discord 

What is GEEK

Buddha Community

Cree Un Bot De Discord Con AWS Lambda + API Gateway

Cree Un Bot De Discord Con AWS Lambda + API Gateway

Recientemente, Discord introdujo interacciones y comandos de barra para facilitar la experiencia de los usuarios con los bots. En parte, el motivo era proteger la privacidad de los usuarios: los bots ahora se ven ligeramente obligados a abandonar las banderas para leer mensajes en los servidores de Discord, lo que anteriormente era un motivo de preocupación con respecto al procesamiento ilegal de datos por parte de los desarrolladores de bots.

Estas son las funciones más conocidas, pero además de eso, la actualización ha agregado la posibilidad de interactuar con las interacciones mencionadas a través de la URL del punto final de interacciones.

Campo del panel del desarrollador para URL de extremo de interacciones.

Esto nos permite pasar de una aplicación de escucha tradicional alojada en un servidor a una aplicación sin servidor *aplausos* , que ejecuta una función Lambda en cada invocación de interacción.

Conexión de AWS Lambda a Discord

Durante la codificación, saltaremos entre "AWS", "Código" y "Portal de desarrolladores de Discord".

AWS

Usaremos AWS API Gateway y AWS Lambda para nuestra tarea. Es un conjunto de herramientas básico para la arquitectura sin servidor en AWS. Las funciones se escribirán en Node.js.

  1. Cree una cuenta e inicie sesión en https://aws.amazon.com
  2. Vaya al servicio API Lambda utilizando la navegación de la barra superior
  3. Elija la sección "Funciones" en la barra lateral (si aún no se ha elegido)
  4. Haga clic en "Crear función"

Página principal de AWS Lambda.

If you were brave enough to click it right away with plugged in credit card — you’ve probably used AWS or AWS Lambda before.

If you hesitated — it’s a moment to calm you down: The AWS Lambda free tier includes one million free requests per month and 400,000 GB-seconds of compute time per month. Way more than you will need for sake of this tutorial and probably ever after (though I wish you exceeding the limit!).

5. Choose your Function name, pick Node.js 14.x and Click “Create function”

Create function panel.

After creation, you should see the dashboard below.

Initial Lambda dashboard. Yeah, we will be clicking like that. Not a point in time to implement IaC.

Great! We have our lambda with a boilerplate code. Now add an API Trigger — we need some URI to pass to Discord Portal, right?

Trigger configuration.

Enable CORS to allow Discord’s host origin. Some day in the future, you may want to change the openness of API endpoint and CORS allowed domains so that you do not get bot-spammed (it’s not common for AWS resources though).

The result:

Trigger created.

Go to the API endpoint by clicking on its URL: you should see “Hello from Lambda!”

Code

Create project directory serverless_discord/. Inside, create a subdirectory lambda_bot/ and index.js within. Use the following code:

const nacl = require('tweetnacl');

exports.handler = async (event) => {
  // Checking signature (requirement 1.)
  // Your public key can be found on your application in the Developer Portal
  const PUBLIC_KEY = process.env.PUBLIC_KEY;
  const signature = event.headers['x-signature-ed25519']
  const timestamp = event.headers['x-signature-timestamp'];
  const strBody = event.body; // should be string, for successful sign

  const isVerified = nacl.sign.detached.verify(
    Buffer.from(timestamp + strBody),
    Buffer.from(signature, 'hex'),
    Buffer.from(PUBLIC_KEY, 'hex')
  );

  if (!isVerified) {
    return {
      statusCode: 401,
      body: JSON.stringify('invalid request signature'),
    };
  }


  // Replying to ping (requirement 2.)
  const body = JSON.parse(strBody)
  if (body.type == 1) {
    return {
      statusCode: 200,
      body: JSON.stringify({ "type": 1 }),
    }
  }
};

In the code above, we follow the structure that you can already see in AWS Lambda boilerplate code (exports.handler function).

Next, we fulfill endpoint requirements (payload verification and ping reply) set by Discord in the documentation. Verification is done with tweetnacl package, that we do not have yet. Let’s install it!

Best case would be if your node --version is close to the Lambda runtime’s version (we chose 14.x ) — ideally, if it’s the same. If it’s too far apart — along with npm — the packed modules may not work in Lambda.

npm i tweetnacl

Good. Now, let’s zip all of that (with node_modules!) and put back into our Lambda. While still being inside of your directory, type:

zip -r ../lambda_bot.zip *

AWS

Upload the zip in Lambda dashboard — section “Code”.

Lambda dashboard.

or through CLI instead, if you have AWS CLI installed and configured:

aws lambda update-function-code \
    --function-name discord \
    --zip-file fileb://../lambda_bot.zip

Everything looks great. Quick app creation at Discord in 3, 2, 1, go!

Discord Developer Portal

Go to Discord Developer Portal, choose New Application and pick a name. Copy previously created API endpoint to Interactions Endpoint URL field in bot’s configuration below.

My real AWS API Gateway URL.

and click Save!

Saving performs Discord-side check of their requirements — they send a set of POST requests to your endpoint.

Scroll to the top of the page for notification and — there you have it! Big Green Success bar — your Bot is live! You made it!

Huh? What? You’ve got some error? Umm, what’s the error message?

You sent me this unhelpful screenshot.

How can I fix the endpoint, when all I know is that “something” is wrong? At most, we may assume, that one of their two requirements is not fulfilled.

AWS

To debug it from AWS side, you can make some test snippets and run them against your code. Unfortunately, it’s not easy to find an exact call example from Discord to mock this.

You can also debug it quickly by running the code on your own computer (just strip the code in index.js from handler function), but you then you’d need external domain redirecting to your local IP, which has its own risks.

Let’s add console logs to have any idea, if the request is coming and if we interpret it correctly.

Add logging in very first lines of index.js

const nacl = require('tweetnacl');exports.handler = async (event) => {
  console.log(event)
  // Checking signature (requirement 1.)
  ...

and click “Deploy”.

In Discord Developer Portal, “Save” Discord Application settings (as a reminder — it will rerun Discord’s POST request to our Lambda). With the event (hopefully) logged, check it in CloudWatch.

Lambda dashboard — navigating to CloudWatch.

I found this error message:

Error message.

(the event itself was logged in one field higher, which may be helpful)

The error points to Line 15 in index.js , which states:

Buffer.from(PUBLIC_KEY, 'hex')

and points rightfully so. We did not pass PUBLIC_KEY environment variable, which is assigned to variable PUBLIC_KEY beforehand.

const PUBLIC_KEY = process.env.PUBLIC_KEY;

Get the Public Key of your app from Discord Developer Portal and insert in AWS Lambda’s: Configuration → Environment Variables → Edit… → Add… (do NOT use quotation marks for env variables)

Key: PUBLIC_KEY, Value: 55ff1c234...

Run “Save Changes” now!

All your edits have been carefully recorded.

Registering and creating Slash Commands

At the end of index.js , add handler for a command, that we will soon register.

I want a Slash Command /foo that replies “bar” (ok, not too mind-blowing).

const nacl = require('tweetnacl');

exports.handler = async (event) => {
  // Checking signature (requirement 1.)
  // Your public key can be found on your application in the Developer Portal
  const PUBLIC_KEY = process.env.PUBLIC_KEY;
  const signature = event.headers['x-signature-ed25519']
  const timestamp = event.headers['x-signature-timestamp'];
  const strBody = event.body; // should be string, for successful sign

  const isVerified = nacl.sign.detached.verify(
    Buffer.from(timestamp + strBody),
    Buffer.from(signature, 'hex'),
    Buffer.from(PUBLIC_KEY, 'hex')
  );

  if (!isVerified) {
    return {
      statusCode: 401,
      body: JSON.stringify('invalid request signature'),
    };
  }


  // Replying to ping (requirement 2.)
  const body = JSON.parse(strBody)
  if (body.type == 1) {
    return {
      statusCode: 200,
      body: JSON.stringify({ "type": 1 }),
    }
  }

  // Handle /foo Command
  if (body.data.name == 'foo') {
    return JSON.stringify({  // Note the absence of statusCode
      "type": 4,  // This type stands for answer with invocation shown
      "data": { "content": "bar" }
    })
  }


  return {
    statusCode: 404  // If no handler implemented for Discord's request
  }
};

Copy and paste the updated code to AWS Lambda code editor or zip it and upload it like the last time. Click “Deploy”.

Registering /foo command

Create a second subdirectory in serverless_discord/ , called register_commands/ , and navigate into it.

➜  serverless_discord mkdir register_commands && cd register_commands

Create a new file register.js with:

require('dotenv').config()
const axios = require('axios').default;

let url = `https://discord.com/api/v8/applications/${process.env.APP_ID}/guilds/${process.env.GUILD_ID}/commands`

const headers = {
  "Authorization": `Bot ${process.env.BOT_TOKEN}`,
  "Content-Type": "application/json"
}

let command_data = {
  "name": "foo",
  "type": 1,
  "description": "replies with bar ;/",
}

axios.post(url, JSON.stringify(command_data), {
  headers: headers,
})

To add missing modules, run:

npm i axios dotenv

But, why do we have two different packages (folders) now?

Well, this one will not be on AWS Lambda and does not have to be anywhere remote, actually. Ideally, registering commands, should happen during CI/CD Pipeline, when there are commands changes. Without CI/CD, it’s totally OK to run the script manually from your local PC after you develop something new.

Create .env file and change values to yours:

BOT_TOKEN=OTYxNzM2M123AB123AB123AB1231
APP_ID=9617363832323452345
GUILD_ID=838565977234523452

ForGUILD_ID, go to Discord App, create a Discord Guild (colloquially Discord Server). In your User Settings → Advanced → Developer Mode ON. Go back to main discord screen, right click on your Guild and click Copy ID.

Then, go to Discord Developer Portal, choose your app → Bot → Add Bot → Reset Token → Copy — it is your BOT_TOKEN.

Find APP_ID in General Information section.

Go to OAuth2 section → URL Generator. Choose Scopes: bot, application.commands. Bot permissions: Use Slash Commands.

Copy URL generated below and visit it — choose Guild, that you have just made.

Generated URL.

You are right, we limit the scope to just one guild (yours). Slash commands will NOT appear in other guilds, that you will invite bot into. When creating Slash Commands with Guild Scope, it applies changes immediately — that’s why it is always used in the development process until the bot is very ready. Creating or changing Global Commands is rolled out for each guild in 0–60 minutes.

Changing scope to Global later on, should take you around 5 minutes with the official documentation.

Enough talking, let’s deploy the command!

➜  register_commands node register.js
➜  register_commands

No error means success! Go quickly to your Discord Guild chat, start typing /foo and press Enter.

Drumroll…

BAR!

Congratulations! 🏆

Your serverless bot is now u̶p̶ ̶a̶n̶d̶ ̶r̶u̶n̶n̶i̶n̶g̶ waiting for events :)

Summary

Upsides:

  1. Low cost
  2. Easy to implement
  3. Very well scalable — no need for sharding (with only linear cost increase!)

Downsides:

  1. Locked to AWS (vendor-lock) (this particular solution)
  2. May require CI/CD implementation more than “serverful” options — otherwise, altering AWS resources may be tedious
  3. This architecture needs proper logging and debug messages on client and server-side in order to be effective.

In this article you have learned:

  1. Basic serverless toolkit on AWS
  2. The current state of Discord Bot programming
  3. Challenges with AWS Lambda — development, deployment, debugging
  4. Payload verification with nacl and making requests with axios

Additional sources:

Climb higher in my next article:

AWS SAM: configuración del desarrollo sin servidor local con Lambda y DynamoDB

Como dice su nueva función, ¡es hora de celebrar en el bar !

(Ahora la imagen de introducción del artículo no se siente tan extraña, ¿verdad?) 

Esta historia se publicó originalmente en https://betterprogramming.pub/build-a-discord-bot-with-aws-lambda-api-gateway-cc1cff750292

#lambda #api #discord 

Anissa  Barrows

Anissa Barrows

1626931020

AWS API Gateway + Lambda /w TypeScript

AWS API Gateway + Lambda /w TypeScript

#aws api #api gateway #api #aws #typescript #lambda

Autumn  Blick

Autumn Blick

1601381326

Public ASX100 APIs: The Essential List

We’ve conducted some initial research into the public APIs of the ASX100 because we regularly have conversations about what others are doing with their APIs and what best practices look like. Being able to point to good local examples and explain what is happening in Australia is a key part of this conversation.

Method

The method used for this initial research was to obtain a list of the ASX100 (as of 18 September 2020). Then work through each company looking at the following:

  1. Whether the company had a public API: this was found by googling “[company name] API” and “[company name] API developer” and “[company name] developer portal”. Sometimes the company’s website was navigated or searched.
  2. Some data points about the API were noted, such as the URL of the portal/documentation and the method they used to publish the API (portal, documentation, web page).
  3. Observations were recorded that piqued the interest of the researchers (you will find these below).
  4. Other notes were made to support future research.
  5. You will find a summary of the data in the infographic below.

Data

With regards to how the APIs are shared:

#api #api-development #api-analytics #apis #api-integration #api-testing #api-security #api-gateway

Build a Serverless API with AWS Gateway and Lambda

APIs are a crucial part of any web application and there are different techniques for development and design. Serverless is one approach gaining popularity, because of its cost-efficiency, scalability and relative simplicity. As a leading serverless provider, Amazon Web Services (AWS) has made a huge contribution to the world of serverless development, and in this article, we will explain general API implementation concepts using AWS Lambda and other AWS services.

Why AWS Lambda?

AWS Lambda is an AWS service that is responsible for running particular functions in response to particular triggers — events happening in the application. Those triggers could be HTTP calls; events from other AWS services like S3, Kinesis, or SNS; or just recurrent scheduled events. Functions are executed in some type of ephemeral containers, which are fully provisioned and scaled by AWS, so the development team can focus more on the code and functionality than on infrastructure.

Another attractive feature is the pay-as-you-go payment model, where you are charged only for the total execution time of your functions and do not pay for idle time. Of course, like any other service, Lambda has limits and is sometimes not suitable for certain tasks — such as very long-running jobs, heavy computing jobs, or processes that require control over the execution environment. However, AWS Lambda usually works perfectly for implementing APIs.

The Role of API Gateway

AWS API Gateway is a service allowing developers to create and manage HTTP endpoints, map them to particular AWS resources, and configure custom domains, authorizing mechanisms, caching and other features. API Gateway is the fundamental part of serverless API, because it is responsible for the connection between a defined API and the function handling requests to that API.

HTTP APIs

As mentioned, API Gateway includes a lot of functionality and integrations. At some point, though, Amazon realized that serverless developers usually do not require all of those features, but instead need a general simplification of the implementation process. That is probably why in late 2019, AWS announced the new HTTP APIs, a lite version of API Gateway, which dramatically simplifies the developer experience and provides better performance and lower costs for serverless APIs. Although it is simple, HTTP APIs still support such important features as configuring CORS for all endpoints, JWT integration, custom domains and VPC connections.

Understanding Serverless API Concepts

In order to easily understand the main concepts of serverless API implementation, we’ll build a very minimalistic example of a simple “virtual whiteboard” application, consisting of two simple endpoints: POST for writing messages on a whiteboard, and GET for fetching the three most recent messages. We will also consider other possible features — like path parameters, CORS, and authorizers — but we’ll keep the final implementation simple and clear to read.

AWS DynamoDB

We will make our project completely serverless, by using AWS DynamoDB for storing messages. This database corresponds to serverless principles, is easy to use, and offers a pay-per-request model that is really cost-effective. DynamoDB is a NoSQL key-value database offered by AWS, where your data is stored across AWS servers and fully managed by Amazon.

AWS Serverless Application Model

In order to continue further implementation, you’ll need an AWS account and AWS Serverless Application Model (SAM) installed and configured. SAM is a tool for creating, updating, and managing serverless applications and all the resources needed for the application to operate. With AWS SAM, you don’t need to create every single service manually via web console, but just to describe all the things needed in the special template file.

After you’ve installed the CLI, navigate to the directory you are going to work in and run this command:

$ sam init -r nodejs12.x -n whiteboard

Initializing new project

Select the first option, then select “Quick Start from Scratch.” This will create a “whiteboard” directory with a minimum of setup files inside.

#api management #aws #api #lambda #aws gateway #amazon web services

Lindsey  Koepp

Lindsey Koepp

1603674601

Integrating API Gateway — Lambda Responses

Probably the most used, versatile and oldest combination between AWS cloud services is REST APIs (public) with Lambda integration on the backend [1]. While RESTful API development is not at all new, if you are relatively new to developing in the cloud, working with these two services may be somewhat challenging. This article requires a basic understanding of these two services. Its focus is beyond the point where you are able to invoke a Lambda function and receive status code 200 from the API. Given the availability of SNS and CloudWatch Logs, why would one bother integrating the API Method & Integration Responses past returning code 200? The answer is that would be a half implemented feature, which lets users speculating about what the result of the invocation was. This article shows how to program an API to return status codes that make sense to your application.

My Use Case

I shall focus on a Lambda function which may throw unexpected exceptions, errors and return a response. To make this more challenging, I am going to use Python. This language is a big hit with developers transitioning from traditional scientific and engineering roles, who have not used any “JS” languages. The intention is to create a foundation on which further API development can be done or at least leave the API in a minimum viable state.

My Solution

I started creating the Lambda function, which I called DanielHTTP. The function uses the latest Python runtime and the IAM policy AWSLambdaBasicExecutionRole which allows CloudWatch logs to be created. I created a role called the same and attached the policy. Alternatively, when this function is created, I could have selected Create New Role to have this done automatically. The function code is available in my GitHub repository [2]. The code is designed to throw an exception by performing an illegal operation, to raise exceptions and errors and to return an Ok response. All cases are individually handled in the API.

#api-gateway #api-development #api-integration #aws-lambda #aws