{
    "componentChunkName": "component---src-templates-post-js",
    "path": "/simple-serverless-now",
    "result": {"data":{"site":{"siteMetadata":{"title":"your friend Joel's digital garden","description":"Articles and notes from a collaborator at egghead.io. Musings on software, business, and life from a skilled virtual assistant.","author":{"name":"Joel Hooks"},"keywords":["Video Blogger"]}},"mdx":{"excerpt":"Serverless functions are incredibly convenient. Being able quickly and easily deply api endpoints with almost zero friction is luxurious! 🥰 One of my primary use cases for serverless functions has been to access and coordinate with third…","fields":{"github":"https://github.com/joelhooks/joelhooks-com/tree/master/content/blog/2019-10-22--creating-a-nodejs-serverless-function-as-a-proxy-endpoint-using-express-on-zeit-now~~-PqgLmfz7/index.mdx"},"body":"var _excluded = [\"components\"];\n\nfunction _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/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"id\": \"-PqgLmfz7\",\n  \"slug\": \"simple-serverless-now\",\n  \"date\": \"2019-10-22T00:00:00.000Z\",\n  \"title\": \"Creating a Node.js serverless function as a proxy endpoint using express on Zeit Now\",\n  \"published\": false\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, _excluded);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"Serverless functions are incredibly convenient. Being able quickly and easily deply api endpoints with almost zero friction is luxurious! \\uD83E\\uDD70\"), mdx(\"p\", null, \"One of my primary use cases for serverless functions has been to access and coordinate with third party APIs. If I'm deploying a static site with Gatsby for instance, I can user a serverless function to add dynamic features and access data across the internet without exposing tokens/secrets or dealing with CORS issues.\"), mdx(\"p\", null, \"An egghead instructor grabbed \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://www.programmableweb.com/api/star-wars-quotes\"\n  }, \"a fun open data Star Wars quote api endpoint\"), \" to use in a code demo. The trouble is, the original URL wasn't using \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"https\"), \" and wouldn't work for demo code in codesandbox.com or on egghead.io which require ssl.\"), mdx(\"p\", null, \"The demo is baked into the videos already, the workshop is scheduled for release, and we needed a quick way to provide the endpoint and still have it function as demonstrated in the videos.\"), mdx(\"p\", null, \"Eventually we'll want to replace the api completely for full control, but to get this solved quickly I wanted to have something under our control that could be deployed to an \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"https\"), \" endpoint and serve as a drop in \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://developer.mozilla.org/en-US/docs/Glossary/Proxy_server\"\n  }, \"proxy server\"), \" for the original URL.\"), mdx(\"p\", null, \"Here are the tools I chose:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"https://expressjs.com/\"\n  }, \"express\"), \" to handle the request and response with convenient middleware\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"https://github.com/axios/axios\"\n  }, \"axios\"), \" to call the original URL being proxied\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function\"\n  }, \"async/await\"), \" to manage the timing of ansync requests and response\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"https://zeit.co/docs/v2/introduction/\"\n  }, \"Zeit's Now\"), \" for deploying configuration free serverless functions\")), mdx(\"p\", null, \"Now is configuration free for simple problems like this. It uses a common convention and the tool inspects the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"/api\"), \" folder for any supported files (\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".js\"), \" in this case) and  creates a \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://zeit.co/docs/v2/serverless-functions/introduction\"\n  }, \"serverless function\"), \" for any that it discovers. \"), mdx(\"p\", null, \"It finds \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"randomQuote.js\"), \" which becomes \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"/api/randomQuote\"), \" on the resulting url when deployed to Now.\"), mdx(\"p\", null, \"-> \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://starwars-quote-proxy-joelhooks.eggheadio1.now.sh/api/randomQuote\"\n  }, \"click here to see it live\")), mdx(\"p\", null, \"In this case, express is being used because it has nifty middleware plugins features like \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://expressjs.com/en/resources/middleware/cors.html\"\n  }, \"cors\"), \" that \\\"just work\\\".\"), mdx(\"p\", null, \"When you call the endpoint, express uses a wild card to handle any incoming requests. \"), mdx(\"p\", null, \"I've read that \\\"express doesn't meet the model of now serverless functions\\\" which I take to mean that you probably shouldn't build a multi-endpoint traditional express app using serverless functions.\"), mdx(\"p\", null, \"This is good advice.\"), mdx(\"p\", null, \"For this problem we are using a single serverless function that uses express for convenience and not to build an \\\"express app\\\". \"), mdx(\"p\", null, \"When the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"/api/randomQuote\"), \" endpoint receives any request it is captured in an \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"async\"), \" function.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-js\"\n  }, \"app.get('*', async (req, res) => {\\n  const response = await axios\\n    .get('http://swquotesapi.digitaljedi.dk/api/SWQuote/RandomStarWarsQuote')\\n    .then(({data}) => {\\n      return data\\n    })\\n\\n  res.send({\\n    ...response,\\n  })\\n})\\n\")), mdx(\"p\", null, \"The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"async\"), \" function assigns a constant \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"response\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"await\"), \"s the response from a call to \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"axios.get\"), \". The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"await\"), \" keyword holds execution of the next line of code until the promise returned by \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"axios.get\"), \" is resolved. \\uD83D\\uDE05\"), mdx(\"p\", null, \"That's a lot going on in a little bit of code. \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"async/await\"), \" is a powerful way to \\\"compress\\\" your code which I recommend learning if it is still unfamiliar. \"), mdx(\"p\", null, \"There's a very good \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://egghead.io/courses/asynchronous-javascript-with-async-await?af=1njoh8\"\n  }, \"egghead course from Marius Schulz on \", mdx(\"inlineCode\", {\n    parentName: \"a\"\n  }, \"async/await\"), \" in JavaScript\"), \" if you'd like to learn more.\"), mdx(\"p\", null, \"Finally, we send a response using \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"res.send\"), \" which forwards the response from the original service back to the caller with no CORS issues to suffer from and using SSL so it works where we need it.\"), mdx(\"p\", null, \"With googling and testing the whole thing took about 20 minutes to put together and push to a live \\\"production\\\" endpoint.\"), mdx(\"p\", null, \"\\uD83D\\uDCAA\"));\n}\n;\nMDXContent.isMDXComponent = true;","frontmatter":{"title":"Creating a Node.js serverless function as a proxy endpoint using express on Zeit Now","date":"October 22, 2019","banner":null,"slug":"simple-serverless-now","keywords":null}}},"pageContext":{"id":"5f292c76-a330-5177-9b49-27562521466a","prev":{"id":"a79327ce-96eb-5e4a-ae76-3ac4ae6f634d","parent":{"name":"index","sourceInstanceName":"blog"},"excerpt":"This is a question that comes up a lot: \"Should I use a framework?\" It's a good question, and something that I've both asked myself and thought about quite a lot over the years. Here's the thing... If you aren't using a framework there is a good…","fields":{"title":"🤔 \"Should I use a framework?\"","slug":"should-i-use-a-framework","date":"2019-11-14T00:00:00.000Z"}},"next":{"id":"ae3f2702-0e9a-5a55-9c74-6eb9f1cdaf74","parent":{"name":"index","sourceInstanceName":"blog"},"excerpt":"Early on when I started learning about business there was a lot of advice about what type of business you can run. You've got Rich Dad Poor Dad describing a real estate empire or E-Myth talking about franchises as systems. It wasn't until I got…","fields":{"title":"💰 Making Other People Money","slug":"make-money","date":"2019-10-09T00:00:00.000Z"}}}},
    "staticQueryHashes": ["1045846374"]}