DEV Community

Ayyash
Ayyash

Posted on • Updated on

The easy straightforward way to create demo serverless functions on Netlify - with CORS

Want to demo out an SPA? or a JAM site? The best way to demo the API calls is to create a real API sitting somewhere and serving static JSON. Much better than creating dummy data "inside" the application.

Netlify

Why? because it is the easiest host to deal with. You can also host on a Free host on Azure, or Blaze free tier of Firebase. But the level of simplicity in Netlify is astonishing.

  • Create a git project on GitHub, Gitlab, or Bitbucket
  • Add a folder: functions
  • Add a new file: demo.js
const demos = require('./demo.json');
exports.handler = async (event) => {
    return {
        statusCode: 200,
        body: JSON.stringify({data: demos})
    }
}
Enter fullscreen mode Exit fullscreen mode

Add a new file: demo.json

[{
    "name": "demo"
}]
Enter fullscreen mode Exit fullscreen mode
  • Commit and push

In Netlify

  • Add a new Site by "import existing project"
  • Select your Git source and skip everything to "Advanced"
  • Type "functions" as your functions directory
  • Save

Now browse to:

https://[yoursite].netlify.app/.netlify/functions/demo

Run it locally:

  • Run npm install netlify-cli -g
  • Run netlify login
  • Run netlify dev -f functions

Now browse to http://localhost:8888/.netlify/functions/demo


Extra step

  • Create file /netlify.toml
  • Add a build segment
[functions]
  directory = "functions"
Enter fullscreen mode Exit fullscreen mode
  • Add also a redirect segment to make your urls... nicer
[[redirects]]
  from = "/api/*"
  to="/.netlify/functions/:splat"
  status=200
Enter fullscreen mode Exit fullscreen mode
  • Commit and push, or run netlify dev

Now you can browse to https://[yoursite].netlify.app/api/demo

Now in your demo.js file handle all HTTP methods, add and remove to your dummy json, the changes will be reset when you commit, or when Netlify decides to restart the server (I think for free tier of all hosts, the server restarts upon request, and stays alive for couple of hours, not sure though).

And to tighten all loose ends, in the toml file, add this

[[headers]]
  for = "/*"
  [headers.values]
    Access-Control-Allow-Origin = '*'
    Access-Control-Allow-Headers = 'Content-Type'
    Access-Control-Allow-Methods = 'GET, POST, PUT, DELETE'
Enter fullscreen mode Exit fullscreen mode

UPDATE: CORS issue

Because the javascript functions are written in **async **method (otherwise a callback that looks ugly and I could not find it well documented). The headers in toml file are too late when you go live (at least on free tier). Solution? Always set headers in all responses. Like this

const demos = require('./demo.json');

const headers = {
    "access-control-allow-origin": "*",
    "Access-Control-Allow-Headers": "Content-Type",
    // don't ever forget the OPTIONS
    "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS"
};

exports.handler = async (event) => {

    return {
        statusCode: 200,
        headers,
        body: JSON.stringify({data: demos})
    }

}
Enter fullscreen mode Exit fullscreen mode

Discussion (0)