Sekrab Garage

Netlify Functions - CORS Updated

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

TipHosting March 1, 22

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 (keep an eye on async)
const demos = require('./demo.json');

exports.handler = async (event) => {

	return {
		statusCode: 200,
		body: JSON.stringify({data: demos})
	}
    
}
  • Add a new file: demo.json

[{
	"name": "demo"
}]
  • 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 in root
  • Add a functions segment (or later as defined in site settings on netlify)
[functions]
  directory = "functions"
  • Add also a redirect segment to make your urls... nicer
[[redirects]]
  from = "/api/*"
  to="/.netlify/functions/:splat"
  status=200
  • 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 decide 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'

But WAIT!

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})
	}
    
}