{"componentChunkName":"component---src-components-posts-page-layout-js","path":"/running-a-serverless-api-using-netlify-functions","result":{"data":{"mdx":{"id":"3d39fed8-f292-55aa-9e41-442057c8cb78","body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"Running a serverless API using Netlify Functions\",\n  \"slug\": \"running-a-serverless-api-using-netlify-functions\",\n  \"date\": \"2020-11-29\",\n  \"author\": \"Adam Goth\",\n  \"preview\": \"Over the last few years, serverless applications have been growing in popularity. There are many use cases in which a serverless solution is more practical and more convenient than the traditional server solution. In this post, we'll look at setting up a serverless Express.js API using Netlify functions.\",\n  \"categories\": [\"development\"],\n  \"keywords\": [\"javascript\", \"serverless\", \"api\", \"web development\", \"express.js\", \"netlify\", \"netlify functions\", \"aws lambda\"]\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"Over the last few years, serverless applications have been growing in\\npopularity. There are many use cases in which a serverless solution is more\\npractical and more convenient than the traditional server solution. In this\\npost, we'll look at setting up a serverless Express.js API using Netlify\\nfunctions.\"), mdx(\"h3\", null, \"Overview\"), mdx(\"p\", null, \"Before we dive into the code for this demo application, let's talk about a few\\nconcepts at a high-level.\"), mdx(\"h3\", null, \"Serverless\"), mdx(\"p\", null, \"\\\"Serverless\\\" is a term that is used for what can generally be thought of as a\\nmethod of providing backend services on an as-used basis. Rather than setting up\\nspecific infrastructure, or a server, to provide the backend services, you can\\nutilize a \\\"serverless\\\" provider to handle this functionality instead. This was\\nfirst popularized by AWS Lambda but is now a service offered by many other\\ncompanies as well, including the one we'll be looking at today, Netlify.\"), mdx(\"h3\", null, \"AWS Lambda\"), mdx(\"p\", null, \"As mentioned above, \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://aws.amazon.com/lambda\"\n  }), \"AWS Lambda\"), \" is the most\\npopular provider of serverless computing. Here's how AWS Lamba describes itself\\nin its own words:\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"AWS Lambda lets you run code without provisioning or managing servers. You pay\\nonly for the compute time you consume.\")), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"With Lambda, you can run code for virtually any type of application or backend\\nservice - all with zero administration. Just upload your code and Lambda takes\\ncare of everything required to run and scale your code with high availability.\\nYou can set up your code to automatically trigger from other AWS services or\\ncall it directly from any web or mobile app.\")), mdx(\"p\", null, \"As great as this sounds (and it really is great), setting up an AWS lambda\\nfunction can be a tedious process, requiring quite a bit of configuration that\\ncan be easily confusing to someone is who new to serverless functions. If you're\\ncurious to see for yourself, here's an\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://docs.aws.amazon.com/toolkit-for-eclipse/v1/user-guide/lambda-tutorial.html\"\n  }), \"example tutorial\"), \"\\ndirectly from the AWS docs. But not to worry, that's why we're here to talk\\nabout Netlify Functions.\"), mdx(\"h3\", null, \"Netlify Functions\"), mdx(\"p\", null, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.netlify.com/products/functions\"\n  }), \"Netlify Functions\"), \" greatly\\nsimplifies the process for running serverless functions. Using Netlify\\nFunctions, we can simply write our lambda function and drop it into the\\nfunctions folder of our Netlify-hosted application. Behind the scenes, Netlify\\nhandles the interaction with AWS for us. We don't even need an AWS account.\\nEvery Netlify account is set up for this feature out of the box. There's no\\nsetup, servers, or ops required.\"), mdx(\"p\", null, \"Let's see what this looks like in code.\"), mdx(\"h3\", null, \"The application\"), mdx(\"p\", null, \"The code for this demo can be found\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/adamgoth/netlify-serverless-demo\"\n  }), \"here\"), \". Since the purpose\\nof this post is to show how to set up a serverless API, rather than do anything\\nspecific with the API, this particular demo application will serve up an\\nextremely basic API with two endpoints that don't do much. I will assume the\\nreader has some basic familiarity with \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://expressjs.com/\"\n  }), \"Express.js\"), \" and\\nNode as we will be using these to build the API.\"), mdx(\"p\", null, \"If we take a look at our package dependencies, we have just five packages:\"), mdx(\"p\", null, mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"nodemon\"), \" is used to automatically restart our server while we're working on it\\nin development\"), mdx(\"p\", null, mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"express\"), \" gives us our API framework\"), mdx(\"p\", null, mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"body-parser\"), \" is middleware that allows us the parse our request bodies\"), mdx(\"p\", null, mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"serverless-http\"), \" allows us to wrap our API for serverless use\"), mdx(\"p\", null, mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"netlify-lambda\"), \" is a tool that helps us build our application code so that it\\ncan be consumed correctly by Netlify using Netlify Functions\"), mdx(\"p\", null, \"The other thing to note in the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"package.json\"), \" file are the two scripts. We have\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"\\\"start\\\": \\\"nodemon server-local.js\\\"\"), \" which is used for development, and\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"\\\"build\\\": \\\"netlify-lambda build express\\\"\"), \" which is used to build and deploy.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"  \\\"scripts\\\": {\\n    \\\"build\\\": \\\"netlify-lambda build express\\\",\\n    \\\"start\\\": \\\"nodemon server-local.js\\\"\\n  }\\n\")), mdx(\"p\", null, \"The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"start\"), \" script is fairly straight forward, it will just execute our\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"server-local.js\"), \" file which in turn is calling \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"express/server.js\"), \". This works\\nfor local development, but we need to do additional work in our \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"build\"), \" script\\nfor the application to work as a serverless function once deployed to Netlify.\\nIn the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"build\"), \" script, we call\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/netlify/netlify-lambda#netlify-lambda-build\"\n  }), mdx(\"inlineCode\", {\n    parentName: \"a\"\n  }, \"netlify-lambda build\")), \"\\nwhich takes a source folder as an argument (\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"express\"), \" in our case) and outputs\\nit to a built folder. The built folder is where Netlify will look for our\\nserverless functions. We have a couple of options for how we specify this. We\\ncould specify the designated folder within Netlify's application settings using\\nNetlify's web app, or within our application code, we can specify the designated\\nfolder with a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"netlify.toml\"), \" configuration file. In our case, we'll use a\\nconfiguration file that lives in our root directory that looks like this:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"// netlify.toml\\n\\n;[build]\\ncommand = \\\"npm install && npm run build\\\"\\nfunctions = \\\"functions\\\"\\n\")), mdx(\"p\", null, \"With our scripts and build configuration accounted for, let's take a look at the\\ncore of the application.\"), mdx(\"p\", null, \"The core of the application lives in the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"express/server.js\"), \" file, and in our\\ncase, is just 29 lines.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"\\\"use strict\\\"\\nconst express = require(\\\"express\\\")\\nconst serverless = require(\\\"serverless-http\\\")\\nconst app = express()\\nconst bodyParser = require(\\\"body-parser\\\")\\nconst router = express.Router()\\n\\napp.use(bodyParser.json())\\napp.use(\\\"/.netlify/functions/server\\\", router) // path must route to lambda\\napp.use(\\\"/\\\", router)\\n\\nrouter.get(\\\"/\\\", (req, res) => {\\n  res.writeHead(200, { \\\"Content-Type\\\": \\\"text/html\\\" })\\n  res.write(\\\"<h1>Up and running</h1>\\\")\\n  res.end()\\n})\\n\\nrouter.post(\\\"/doSomething\\\", async (req, res) => {\\n  try {\\n    // maybe do some database interaction or third-party API call here!\\n    res.status(200).send({ data: \\\"success\\\" })\\n  } catch (err) {\\n    console.log(err)\\n    res.status(400).send({ error: \\\"bad request\\\" })\\n  }\\n})\\n\\nmodule.exports = app\\nmodule.exports.handler = serverless(app)\\n\")), mdx(\"p\", null, \"If you've ever worked with Express.js, this should look pretty familiar to you.\\nWe have two endpoints, one \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"GET\"), \" endpoint at \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"/\"), \" and one \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"POST\"), \" endpoint at\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"/doSomething\"), \".\"), mdx(\"p\", null, \"These endpoints don't do much, but you could do just about anything you would\\nnormally do with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"GET\"), \" or \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"POST\"), \" endpoints here. Hit a third-party API, connect\\nto a database, fire off some sort of transaction, etc.\"), mdx(\"p\", null, \"The two lines in the application that are specific to using Netlify's serverless\\nfunctions are line 9 and line 29.\"), mdx(\"p\", null, \"As we specified in our \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"netlify.toml\"), \" configuration file, our function code is\\ngoing to live at \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"./netlify/functions/server\"), \". So we will tell our express app\\non line 9 to use our \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"router\"), \" object anytime a request is sent to this server.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"app.use(\\\"/.netlify/functions/server\\\", router)\\n\")), mdx(\"p\", null, \"Lastly, on line 29, we will utilize the\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/dougmoscrop/serverless-http\"\n  }), mdx(\"inlineCode\", {\n    parentName: \"a\"\n  }, \"serverless-http\")), \" package to\\nwrap our application up for serverless use. This means our application can work\\nas expected without any HTTP server, ports, or sockets.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"module.exports.handler = serverless(app)\\n\")), mdx(\"p\", null, \"With that, the application is all set to\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://docs.netlify.com/site-deploys/overview/#deploy-summary\"\n  }), \"deploy to Netlify\"), \".\\nIf you've never deployed on Netlify before, you'll be amazed at how simple it\\nis. This post won't go into details but it isn't much more than authenticating\\nyour GitHub account and selecting the repo and branch to deploy. Once the\\napplication is deployed, you can start accessing the endpoints we created at\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"<your site URL>/.netlify/functions/server/<your endpoint>\"), \". We now have a basic\\nyet fully-functioning API, without having to run or provision a dedicated and\\nseparate server!\"), mdx(\"h3\", null, \"Wrapping up\"), mdx(\"p\", null, \"Hopefully you were able to follow along in creating this Netlify serverless\\nfunction. Serverless computing is still a developing and evolving technology but\\nits popularity continues to grow as more developers find it more suitable to\\ntheir needs than traditional server applications.\"), mdx(\"p\", null, \"The particular use case that led me to using Netlify functions is that I needed\\nto make a third-party API call from my client application that required a\\nprivate API key in the header. With just client-side code, there is no good way\\nto keep your private API key private. I decided I needed a server to proxy the\\nrequest through, but I didn't want to create and dedicate an entire server just\\nto pass one small API request through. So this ended up being a perfect\\nsolution. Now that I know how convenient and simple this can be, I will be\\nlooking for more opportunities to utilize Netlify Functions.\"), mdx(\"p\", null, \"For more technical information regarding the usage and implementation of Netlify\\nFunctions, be sure to visit\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://docs.netlify.com/functions/overview/#manage-your-serverless-functions\"\n  }), \"the docs\"), \".\"), mdx(\"p\", null, \"If you enjoyed this post or found it useful, please consider\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.adamgoth.com%2Frunning-a-serverless-api-using-netlify-functions\"\n  }), \"sharing it on Twitter\"), \".\"), mdx(\"p\", null, \"If you want to stay updated on new posts,\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://twitter.com/intent/follow?original_referer=https%3A%2F%2Fpublish.twitter.com%2F%3FbuttonType%3DFollowButton%26query%3Dhttps%253A%252F%252Ftwitter.com%252Finit_adam%26widget%3DButton&ref_src=twsrc%5Etfw&region=follow_link&screen_name=init_adam&tw_p=followbutton\"\n  }), \"follow me on Twitter\"), \".\"), mdx(\"p\", null, \"If you have any questions, comments, or just want to say hello,\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://twitter.com/messages/compose?recipient_id=33618361\"\n  }), \"send me a message\"), \".\"), mdx(\"p\", null, \"Thanks for reading!\"));\n}\n;\nMDXContent.isMDXComponent = true;","frontmatter":{"title":"Running a serverless API using Netlify Functions","date":"2020-11-29","author":"Adam Goth","preview":"Over the last few years, serverless applications have been growing in popularity. There are many use cases in which a serverless solution is more practical and more convenient than the traditional server solution. In this post, we'll look at setting up a serverless Express.js API using Netlify functions.","keywords":["javascript","serverless","api","web development","express.js","netlify","netlify functions","aws lambda"]},"timeToRead":5}},"pageContext":{"id":"3d39fed8-f292-55aa-9e41-442057c8cb78"}},"staticQueryHashes":["63159454"]}