Project Two: Your First API
Overview
This second project is your first foray into building a full-stack application. You'll be building a Node/Express/MongoDB app from the ground up yourself. This would be the backend portion of a Modern MERN Stack App.
VIEWS AND VIEW ENGINES ARE NOT A PART OF THIS PROJECT
You will be working individually for this project;
You get to decide what you want to build - as long as it meets the technical requirements outlined below.
Technical Requirements
Your App Must:
☐ Have at least 2 data entities in total at minimum, so one "User" schema & model and another schema & model that represents the main functional idea for your app (relationships between entities are encouraged, but not required)
☐ Use JWT authentication.
☐ Have complete CRUD data operations on one of your data entities. i.e Create
A Fruit, Read
via Index of all Fruits & Show a Fruits, Update
A Fruit, Delete
a Fruit
☐ Be available on Github.com (NOT ENTERPRISE) without your .env
or node_modules
(because of .gitignore
) and your readme must be detailed.
Optionally, Your App May:
☐ Build a Front End App that calls your API (see the MERN Stack Mastery Videos on my Youtube)
Necessary Deliverables
☐ Github Repo & README
Suggested Ways to Get Started
- Because your app's functionality revolves around the logged in user, implement authentication first!
- Discuss your api idea with an instructor to get their feedback before you dive too deep into user stories and wireframes.
- Remember to keep things small and focus on the MVP – feature creep can doom a project!
Project Idea Guidance (In order of complexity)
- Create A Fruits List API (User, Fruits) 4 - 8 hours of Engineering, Including Wireframes, Building API and Testing it Manually & Automatically via JEST & SUPERTEST
- Create A Blog API (User, Posts) 12 - 20 hours
- Create A TodoList API (Users & Todo Items) 12 - 20 hours
- Create A Shopping Cart (Users, Carts/Orders, Items) 40 - 60 hours
- Create An Event Tracker (Users, Events, Attendees) 80 - 100 hours
- Create A Trello Board API (Users, Boards, Columns, Tasks) 80 - 100 hours
- Create A Grade Book API (Teacher, Subjects, Classes, Students, Assignments) 100 - 120 hours
These hours are in addition to the time it takes you to:
- Make a Readme
If you come up with your own, anything that require more than 2 Models must be approved by Arthur
Other Project API Ideas
- Bookmarks: As a user i can add my favorite websites to a list only i can see
- Notes App: As a user, I can create, edit, and delete notes, categorize them, and search through my notes.
- Expense Tracker: As a user, I can log expenses, categorize them, and view a summary of my spending.
- Event Planner: As a user, I can schedule events, set reminders, and track upcoming events.
- Fitness Tracker: As a user, I can record my workouts, track progress, and set fitness goals.
- Recipe Book: As a user, I can add, edit, and search for recipes, and list ingredients for shopping.
- Reading List: As a user, I can maintain a list of books, mark them as read, and add reviews.
- Personal Diary: As a user, I can write diary entries, tag them, and browse through past entries.
- Habit Tracker: As a user, I can track daily habits, set goals, and view my streaks.
- Budget Planner: As a user, I can create a budget, log transactions, and view financial summaries.
- Travel Journal: As a user, I can document my trips, add locations, and share experiences.
- Goal Setter: As a user, I can set personal goals, track milestones, and monitor my progress.
- Music Playlist Organizer: As a user, I can create playlists, add songs, and categorize them.
- Language Learning Log: As a user, I can track new words, practice them, and monitor my learning.
- Movie Watchlist: As a user, I can add movies to my watchlist, mark them watched, and leave comments.
- Daily Planner: As a user, I can schedule tasks, set reminders, and organize my day.
- Pet Care Log: As a user, I can track my pet’s activities, set reminders for care, and log vet visits.
- Study Planner: As a user, I can organize study sessions, set goals, and track subjects.
- Job Application Tracker: As a user, I can track job applications, set follow-up reminders, and note outcomes.
- Gift Ideas Organizer: As a user, I can note gift ideas, link them to occasions, and track purchases.
- Skill Learning Tracker: As a user, I can record new skills I’m learning, track my progress, and set learning goals.
- Gardening Helper: As a user, I can keep a log of my plants, schedule care tasks, and track growth.
- Meal Planner: As a user, I can plan meals for the week, save recipes, and track nutritional intake.
- Book Club Organizer: As a user, I can schedule club meetings, discuss books, and share reading lists.
- Sports Team Manager: As a user, I can manage team rosters, schedule matches, and track results.
- Daily Affirmations: As a user, I can create and view daily affirmations, and track my mood over time.
- Water Intake Tracker: As a user, I can log daily water intake, set hydration goals, and view trends.
- Personal Inventory: As a user, I can catalog my belongings, categorize items, and track lending.
- Volunteer Activity Tracker: As a user, I can log volunteer hours, track activities, and set goals.
- Podcast Tracker: As a user, I can keep track of podcasts I listen to, mark episodes, and note favorites.
- Art Portfolio: As a user, I can showcase my artworks, organize them into collections, and share them.
- Sleep Tracker: As a user, I can log sleep hours, rate sleep quality, and view sleep patterns.
- Weather Tracker: As a user, I can log weather conditions daily and view historical weather data.
- Local Restaurant Guide: As a user, I can explore restaurants, rate them, and save favorites.
- Personal Time Tracker: As a user, I can track time spent on various activities and analyze productivity.
- Daily Quote App: As a user, I can view daily quotes, save favorites, and share them with others.
- Public Speaking Progress Tracker: As a user, I can log speeches, track improvements, and set goals.
- Simple Blogging Platform: As a user, I can write and publish blog posts, and interact with readers.
- Homework Reminder App: As a user, I can track homework assignments and set due date reminders.
- Personal Finance Advisor: As a user, I can receive financial tips and track my financial learning.
- Concert Memory Keeper: As a user, I can log concerts I’ve attended, add setlists, and share my experiences.
- Comic Book Collection: As a user, I can catalog my comic books, track issues, and rate them.
- Local Cafe Guide: As a user, I can discover cafes nearby, save favorites, and leave reviews.
- Gym Workout Log: As a user, I can record my exercises, track progress, and set fitness goals.
- Mindfulness Tips App: As a user, I can access daily mindfulness tips, track practices, and note effects.
- Vegan Recipe Sharing: As a user, I can share vegan recipes, save favorites, and comment on others.
Presentation Steps
- Go to your github and show your Readme (no read me, no pass)
- Grab your clone link
- Clone your repo to your computer
- Follow your install instructions
- Run your tests
- Explain your models
- Stop presenting, you're done.
Example readme instructions
https://earnings-api.gapgambler.com
Node version must be version 18 to work with api locally and must create .env with MONGO_URI & sha256 SECRET + Must have nodemon installed global
.env example
SECRET=eb5021b23fe31b9f16e0c05b60dadb6744575184efc1b956887b41c7cc97b17e
MONGO_URI=mongodbLink
SECRET must be a sha256 hash https://emn178.github.io/online-tools/sha256.html
NEW UPDATE ADDED /earnings/stock/index as an index of stocks && its public along with earnings/stock/:ticker
User routes
/users/index
Get Request
Returns all users
No Body Sent
Authorization Header
With Bearer Token Bearer <token>
/users/login
Post Request Returns an Object
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY0YWJiYmJhZGY3ZTU1MTYwMmE1MTE2NiIsIm5hbWUiOiJhcnRodXIiLCJlbWFpbCI6ImFAOC5jb20iLCJwaG9uZSI6IjEyMzQ1Njc4OCIsImlhdCI6MTY4ODk4MTY4NH0.E0YQw0wNTkxIam0IVpjICLAV47IahALapdBPUdRQKIg",
"points": 0,
"votes": [...votesHere],
"_id": "64abbbbadf7e551602a51166",
"name": "arthur",
"email": "a@8.com",
"phone": "123456788",
"__v": 0
}
No Authorization Header
/users/signup
Post Request
Returns an Object
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY0YWJiYmJhZGY3ZTU1MTYwMmE1MTE2NiIsIm5hbWUiOiJhcnRodXIiLCJlbWFpbCI6ImFAOC5jb20iLCJwaG9uZSI6IjEyMzQ1Njc4OCIsImlhdCI6MTY4ODk4MTY4NH0.E0YQw0wNTkxIam0IVpjICLAV47IahALapdBPUdRQKIg",
"points": 0,
"votes": [...votesHere],
"_id": "64abbbbadf7e551602a51166",
"name": "arthur",
"email": "a@8.com",
"phone": "123456788",
"__v": 0
}
No Authorization Header
/users/show/:id
Get Request
Returns one user
No Body Sent
Authorization Header
With Bearer Token Bearer <token>
/users/update/:id
Put Request Returns user
{
key: value,
...asManyKeysAsYouWantToChange
}
Authorization Header
With Bearer Token Bearer <token>
If token and params don't match errors on purpose
/users/delete/:id
Delete Request
Returns Nothing But Sends 204 Response
No Body Sent
Authorization Header
With Bearer Token Bearer <token>
If token and params don't match errors on purpose
Earnings Routes
/earnings/vote/:ticker
POST Request
Returns User with Votes Populated each Vote
has 1 or 2 responses
most days there is only 1 question But last day has 2 questions
{
"points": 0,
"votes": [
{
"responses": [
{
"_id": "64abd53ac6e8c41f13fd5c02",
"question": {
"acceptableAnswers": [
"0% to 3.99%",
"4% to 7.99%",
"8% or More"
],
"_id": "64abc3de16590d197f25b045",
"text": "What is the magnitude of the gap?",
"questionID": 2,
"__v": 0
},
"answer": "0% to 3.99%",
"__v": 0
}
],
"_id": "64abd53ac6e8c41f13fd5bfe",
"user": "64abbbbadf7e551602a51166",
"stockPick": "64abc3de16590d197f25b02e",
"__v": 1
},
{
"responses": [
{
"_id": "64abdab927bba31faf94af99",
"question": {
"acceptableAnswers": [
"0% to 3.99%",
"4% to 7.99%",
"8% or More"
],
"_id": "64abc3de16590d197f25b045",
"text": "What is the magnitude of the gap?",
"questionID": 2,
"__v": 0
},
"answer": "0% to 3.99%",
"__v": 0
}
],
"_id": "64abdab927bba31faf94af95",
"user": "64abbbbadf7e551602a51166",
"stockPick": "64abc3de16590d197f25b02e",
"__v": 1
},
{
"responses": [
{
"_id": "64abdb1753db2d1fdde81814",
"question": {
"acceptableAnswers": [
"up",
"down"
],
"_id": "64abc3de16590d197f25b044",
"text": "Will this stock gap up or down?",
"questionID": 1,
"__v": 0
},
"answer": "up",
"__v": 0
},
{
"_id": "64abdb1753db2d1fdde81815",
"question": {
"acceptableAnswers": [
"0% to 3.99%",
"4% to 7.99%",
"8% or More"
],
"_id": "64abc3de16590d197f25b045",
"text": "What is the magnitude of the gap?",
"questionID": 2,
"__v": 0
},
"answer": "0% to 3.99%",
"__v": 0
}
],
"_id": "64abdb1753db2d1fdde81810",
"user": "64abbbbadf7e551602a51166",
"stockPick": "64abc3de16590d197f25b02e",
"__v": 1
},
{
"responses": [
{
"_id": "64abdb5953db2d1fdde81825",
"question": {
"acceptableAnswers": [
"up",
"down"
],
"_id": "64abc3de16590d197f25b044",
"text": "Will this stock gap up or down?",
"questionID": 1,
"__v": 0
},
"answer": "up",
"__v": 0
},
{
"_id": "64abdb5953db2d1fdde81826",
"question": {
"acceptableAnswers": [
"0% to 3.99%",
"4% to 7.99%",
"8% or More"
],
"_id": "64abc3de16590d197f25b045",
"text": "What is the magnitude of the gap?",
"questionID": 2,
"__v": 0
},
"answer": "0% to 3.99%",
"__v": 0
}
],
"_id": "64abdb5853db2d1fdde81821",
"user": "64abbbbadf7e551602a51166",
"stockPick": "64abc3de16590d197f25b02e",
"__v": 1
}
],
"_id": "64abbbbadf7e551602a51166",
"name": "arthur",
"email": "a@8.com",
"phone": "123456788",
"password": "$2a$08$rDTivf.xwtI1xjb8PkFCzODpHR/gpR61G2fmcUcfGBW7ViJOGq/.W",
"__v": 8
}
What you need to send
date format is a string seperated by /
- first number Month
- second number day
- third is year in 4 digit format
- fourth time in eastern standard time in 24hr aka Military time
- frontend must send the date and time (in est) of when the vote is being cast so we know if it should be counted
- example 7/9/2023/2359 is July 9, 2023 at 23:59 aka 11:59pm EST
- If the stock has a
votingCloses
property of7/10/2023/1630
then this could be submitted but if it was7/9/2023/1630
the submission would fail on purpose
{
"date":"7/9/2023/2359",
"responses": [
{
"questionID": 1,
"responseText": "up"
},
{
"questionID": 2,
"responseText":"0% to 3.99%"
}
]
}
/earnings/stock/:ticker
Get Request No Body Sent Returns A Stocks Data
{
"_id": "64abc3de16590d197f25b02e",
"ticker": "WDFC",
"earningsDate": "7/10/2023/1630",
"votingCloses": "7/10/2023/1630",
"previousGap1": -5.07,
"previousGap2": -0.37,
"previousGap3": -6.77,
"previousGap4": -12.03,
"previousGap1Date": "4/6/2023/1630",
"previousGap2Date": "1/9/2023/1630",
"previousGap3Date": "10/19/2022/1630",
"previousGap4Date": "7/7/2022/1630",
"symbol": "WDFC - 7/10/2023/1630",
"__v": 0
}
Questions & Stocks are hard coded via Seed File
require('dotenv').config()
require('mambascript').register()
User = require './models/user'
Vote = require './models/vote'
Response = require './models/response'
StockPick = require './models/stockPick'
Question = require './models/question'
mongoose = require 'mongoose'
mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true
useUnifiedTopology: true
useCreateIndex: true
useFindAndModify: false
})
mongoose.connection.once 'open', -> present 'Mongo is showing love'
(->
Question.deleteMany({}).then(->
Question.create([
{
text: 'Will this stock gap up or down?'
questionID: 1
acceptableAnswers: ['up', 'down']
},
{
text: 'What is the magnitude of the gap?'
questionID: 2
acceptableAnswers: ['0% to 3.99%', '4% to 7.99%', '8% or More']
}
])
)
StockPick.deleteMany({}).then(->
StockPick.create([
{
ticker: 'WDFC'
earningsDate: '7/10/2023/1630'
votingCloses: '7/10/2023/1630'
previousGap1: -5.07
previousGap2: -0.37
previousGap3: -6.77
previousGap4: -12.03
previousGap1Date: '4/6/2023/1630'
previousGap2Date: '1/9/2023/1630'
previousGap3Date: '10/19/2022/1630'
previousGap4Date: '7/7/2022/1630'
},
{
ticker: 'BYRN'
earningsDate: '7/11/2023/1630'
votingCloses: '7/10/2023/1630'
previousGap1: -5.07
previousGap2: -0.37
previousGap3: -6.77
previousGap4: -12.03
previousGap1Date: '4/6/2023/1630'
previousGap2Date: '1/9/2023/1630'
previousGap3Date: '10/19/2022/1630'
previousGap4Date: '7/7/2022/1630'
},
{
ticker: 'ANGO'
earningsDate: '7/12/2023/1630'
votingCloses: '7/11/2023/1630'
previousGap1: -5.07
previousGap2: -0.37
previousGap3: -6.77
previousGap4: -12.03
previousGap1Date: '4/6/2023/1630'
previousGap2Date: '1/9/2023/1630'
previousGap3Date: '10/19/2022/1630'
previousGap4Date: '7/7/2022/1630'
},
{
ticker: 'PEP'
earningsDate: '7/13/2023/1630'
votingCloses: '7/12/2023/1630'
previousGap1: -5.07
previousGap2: -0.37
previousGap3: -6.77
previousGap4: -12.03
previousGap1Date: '4/6/2023/1630'
previousGap2Date: '1/9/2023/1630'
previousGap3Date: '10/19/2022/1630'
previousGap4Date: '7/7/2022/1630'
},
{
ticker: 'WFC'
earningsDate: '7/14/2023/1630'
votingCloses: '7/13/2023/1630'
previousGap1: -5.07
previousGap2: -0.37
previousGap3: -6.77
previousGap4: -12.03
previousGap1Date: '4/6/2023/1630'
previousGap2Date: '1/9/2023/1630'
previousGap3Date: '10/19/2022/1630'
previousGap4Date: '7/7/2022/1630'
},
{
ticker: 'IBM'
earningsDate: '7/17/2023/1630'
votingCloses: '7/14/2023/1630'
previousGap1: -5.07
previousGap2: -0.37
previousGap3: -6.77
previousGap4: -12.03
previousGap1Date: '4/6/2023/1630'
previousGap2Date: '1/9/2023/1630'
previousGap3Date: '10/19/2022/1630'
previousGap4Date: '7/7/2022/1630'
},
{
ticker: 'BAC'
earningsDate: '7/18/2023/1630'
votingCloses: '7/17/2023/1630'
previousGap1: -5.07
previousGap2: -0.37
previousGap3: -6.77
previousGap4: -12.03
previousGap1Date: '4/6/2023/1630'
previousGap2Date: '1/9/2023/1630'
previousGap3Date: '10/19/2022/1630'
previousGap4Date: '7/7/2022/1630'
},
{
ticker: 'ELV'
earningsDate: '7/19/2023/1630'
votingCloses: '7/18/2023/1630'
previousGap1: -5.07
previousGap2: -0.37
previousGap3: -6.77
previousGap4: -12.03
previousGap1Date: '4/6/2023/1630'
previousGap2Date: '1/9/2023/1630'
previousGap3Date: '10/19/2022/1630'
previousGap4Date: '7/7/2022/1630'
},
{
ticker: 'JNJ'
earningsDate: '7/20/2023/1630'
votingCloses: '7/19/2023/1630'
previousGap1: -5.07
previousGap2: -0.37
previousGap3: -6.77
previousGap4: -12.03
previousGap1Date: '4/6/2023/1630'
previousGap2Date: '1/9/2023/1630'
previousGap3Date: '10/19/2022/1630'
previousGap4Date: '7/7/2022/1630'
},
{
ticker: 'ALV'
earningsDate: '7/21/2023/1630'
votingCloses: '7/20/2023/1630'
previousGap1: -5.07
previousGap2: -0.37
previousGap3: -6.77
previousGap4: -12.03
previousGap1Date: '4/6/2023/1630'
previousGap2Date: '1/9/2023/1630'
previousGap3Date: '10/19/2022/1630'
previousGap4Date: '7/7/2022/1630'
},
{
ticker: 'DPZ'
earningsDate: '7/24/2023/1630'
votingCloses: '7/21/2023/1630'
previousGap1: -5.07
previousGap2: -0.37
previousGap3: -6.77
previousGap4: -12.03
previousGap1Date: '4/6/2023/1630'
previousGap2Date: '1/9/2023/1630'
previousGap3Date: '10/19/2022/1630'
previousGap4Date: '7/7/2022/1630'
},
])
)
)()