Last active
November 5, 2018 09:28
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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