Skip to content

Instantly share code, notes, and snippets.

@bcnzer
Last active November 5, 2018 09:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bcnzer/412203a71819e86c3ecf0d0ddf1770c1 to your computer and use it in GitHub Desktop.
Save bcnzer/412203a71819e86c3ecf0d0ddf1770c1 to your computer and use it in GitHub Desktop.
Sample Worker and KV code to demonstrate GETs that are purely handled on the edge - both the request AND data
// NOTE: all auth code has been removed for the sake of brevity. Please see part 2 of blog series
// for more info: https://liftcodeplay.com/2018/10/16/pushing-my-api-to-the-edge-part-2-authentication-and-authorization/
addEventListener('fetch', event => {
event.respondWith(handleRequest(event))
})
const genderFemale = 'Female'
const genderMale = 'Male'
/**
* Entry point of the worker
*/
async function handleRequest(event) {
// Generate the CORS headers I'll have to return with requests
const corsHeaders = setCorsHeaders(new Headers())
try {
const requestMethod = event.request.method
const requestUrl = new URL(event.request.url)
console.log(requestUrl)
// Always return the same CORS info
if(requestMethod === 'OPTIONS') {
return new Response('', { headers:corsHeaders })
}
// GET the competition info from KV
const entryRegex = /^\/v1\/entry\/\d+$/ // i.e. /v1/entry/17043
if (requestMethod === 'GET' && requestUrl.hostname === 'api.powerlifting.com' && entryRegex.test(requestUrl.pathname)) {
const entryCompId = requestUrl.pathname.split('/')[3]
console.log(entryCompId)
const entryData = await SIGNUP_DATA.get(entryCompId)
return new Response(entryData, { status: 200, headers:corsHeaders })
}
// Get ALL the WEIGHT CLASSES and DIVISIONS from KV and return them
if (requestMethod === 'GET' && requestUrl.hostname === 'api.powerlifting.com' && requestUrl.pathname === '/v1/entry/weightclassanddivisons') {
return getWeightClassAndDivisions(corsHeaders)
}
// Get the DIVISIONS from KV and return them
if (requestMethod === 'GET' && requestUrl.hostname === 'api.powerlifting.com' && requestUrl.pathname === '/v1/entry/divisions') {
return getDivisions(requestUrl, corsHeaders)
}
// Get the WEIGHT CLASSES from KV and return them
if (requestMethod === 'GET' && requestUrl.hostname === 'api.powerlifting.com' && requestUrl.pathname === '/v1/entry/weightclasses') {
return getWeightClasses(requestUrl, corsHeaders)
}
const response = await fetch(event.request)
return response
}
catch (err) {
return new Response(err.stack, { status: 500, headers:corsHeaders })
}
}
/**
* Setup the CORS headers to the details
*/
function setCorsHeaders(headers) {
headers.set('Access-Control-Allow-Origin', '*') // Not a good idea to leave it to wildcard; I'm only doing so for initial testing/dev
headers.set('Access-Control-Allow-Methods', 'POST, GET')
headers.set('Access-Control-Allow-Headers', 'access-control-allow-headers, g-recaptcha')
headers.set('Access-Control-Max-Age', 1728000)
return headers
}
/**
* Get the static DIVISIONS from KV and return them
*/
async function getDivisions(requestUrl, corsHeaders) {
const age = requestUrl.searchParams.get('age')
const gender = requestUrl.searchParams.get('gender')
if (!!gender && gender !== genderFemale && gender !== genderMale) {
return new Response('', { status: 400, headers:corsHeaders })
}
const storedDivisions = await SIGNUP_DATA.get('ipf2018')
let divisions = JSON.parse(storedDivisions).divisions
if (!!age || !!gender) {
divisions = divisions.filter(function(div) {
if (!!age && !!gender) {
// If you specify an age you must specify a gender
return age >= div.startAge && age <= div.endAge && gender === div.gender
} else if (!age && !!gender) {
// It's fine if you just specify a gender
return gender === div.gender
} else if (!!age && !gender) {
// Not ok if you specify an age but no gender
return false
}
// Return everything
return true
})
}
divisions = divisions.map(function(div) {
return {
"gender": div.gender,
'name': div.name,
'abbrev': div.abbrev
}
})
console.log(divisions)
return new Response(JSON.stringify(divisions), { status: 200, headers:corsHeaders })
}
/**
* Get the static WEIGHT CLASSES from KV and return them
*/
async function getWeightClasses(requestUrl, corsHeaders) {
const weight = requestUrl.searchParams.get('weight')
const gender = requestUrl.searchParams.get('gender')
if (!!gender && gender !== genderFemale && gender !== genderMale) {
return new Response('', { status: 400, headers:corsHeaders })
}
const storedWeightClasses = await SIGNUP_DATA.get('ipf2018')
let weightClasses = JSON.parse(storedWeightClasses).weightClasses
if (!!weight) {
weightClasses = weightClasses.filter(function(wc) {
return weight >= wc.startWeight && weight <= wc.endWeight
})
}
if (!!weight || !!gender) {
weightClasses = weightClasses.filter(function(wc) {
if (!!weight && !!gender) {
// If you specify an weight you must specify a gender
return weight >= wc.startWeight && weight <= wc.endWeight && gender === wc.gender
} else if (!weight && !!gender) {
// It's fine if you just specify a gender
return gender === wc.gender
} else if (!!weight && !gender) {
// Not ok if you specify a weight but no gender
return false
}
// Return everything
return true
})
}
weightClasses = weightClasses.map(function(wc) {
return {
"gender": wc.gender,
'name': wc.name
}
})
console.log(weightClasses)
return new Response(JSON.stringify(weightClasses), { status: 200, headers:corsHeaders })
}
/**
* Get all the weight classes and divisions, for both headers, and return it as one data set
*/
async function getWeightClassAndDivisions(corsHeaders) {
let storeData = await SIGNUP_DATA.get('ipf2018')
return new Response(storeData, { status: 200, headers:corsHeaders })
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment