Hi everyone,So of course I'm not very experienced in this area, and was hoping for some guidance/advice.I'm working on a personal project of mine and I was designing some routes. I came up with a working solution but it doesn't seem very "elegant". Essentially, it just takes the url path and uses lots of if statements to determine what to send back.I was wondering if anyone had any suggestions on how they might design it, or if the way I came up with is totally valid.This is for some sportsbooks so what I'm trying to do is this:api/books returns all the books supported by my api, so this might return something like ["Draftkings", "Fanduel"]api/:book returns all the sports available on the sportsbook, for example api/fanduel might return ["NFL", "NBA"]. If book doesn't exist it might just return 404.api/:book:/:sport would return some data about the sport I have yet to decide yet. Of course, the sport would have to exist for said sportsbook.My implementation looks like:app.js://... app.use(express.json()) app.use('/api', router) app.use(middleware.unknownEndpoint) //... router.js:const router = require('express').Router() //Temp database const bookData = [ { book: 'DraftKings', sports: [ 'NFL', 'UFC', 'CF' ] }, { book: 'FanDuel', sports: [ 'NFL', 'UFC', 'CF' ] }, { book: 'PointsBet', sports: [ 'NFL', 'UFC', 'CF' ] } ] router.get('/:book?/:sport?', (request, response, next) => { //This get path will be processed from left to right, like a tree structure / file structure //First validate book parameter //Then check if sport is defined or not let book = request.params.book if (!book) { next() } else { book = book.toUpperCase() //Check what the value of book is, do we have it listed in our db? (db is just the array at top named books) if (!bookData.find(r => r.book.toUpperCase() === book) && book !== 'BOOKS') { console.log('Unknown book') next() } else { //Now since book is found, we need to decide what book it is specifically let sport = request.params.sport if (!sport) { //Since sport is undefined/falsy, our path looks something like: api/:book //Do a simple decision here: api/books returns lists of books, but api/:book will return all the supported sports if (book === 'BOOKS') { response.json({ books: bookData.map(entry => entry.book) }) } else { response.json({ sports: bookData.find(b => b.book.toUpperCase() === book).sports }) } } else { //We are at the path /api/:book/:sport since sport is defined as something sport = sport.toUpperCase() //Change the value of book, so it refers to an object instead of a name we're looking for book = bookData.find(b => b.book.toUpperCase() === book) if (!book) { console.log('/api/books/:sport is not a supported path') next() } else if (!book.sports.find(s => s.toUpperCase() === sport) && sport !== 'SPORTS') { console.log('Known book, but unknown/unsupported sport') next() } else { response.json({ message: 'All matchups for the sport will be listed here. Will implement api/:book/:sport/:matchup next to display odds/spread data scraped from the books' }) } } } } }) router.get('/', (request, response) => { response.json({bookData}) }) module.exports = router The code does work as intended, but I'm sure it would start to get very muddled if I start adding more and more url parameters. I wanted to do something like a nested router, but I'm not sure if that's an actual thing. Any advice is helpful and appreciated!
Submitted June 05, 2020 at 03:23AM by bakedziti88
No comments:
Post a Comment