Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Week 19: happy thoughts API #509

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
# Project Happy Thoughts API

Replace this readme with your own information about your project.

Start by briefly describing the assignment in a sentence or two. Keep it short and to the point.
This project is a simple REST API for storing, retrieving, and liking “Happy Thoughts”. Inspired by Twitter, but focusing on positivity. It includes endpoints to get recent thoughts, post new ones, and “like” them.

## The problem

Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next?
I wanted to build an API that could integrate easily with a React frontend for a “happy thoughts” feed. The main goals were:

To practice designing a MongoDB-backed API with Mongoose models.
To handle data validation (e.g., message length limits).
To deploy the API so that it can be used in a production-like setting.
Tools & Techniques
Node.js / Express for the server.
Mongoose for modeling and validation.
MongoDB for storage (hosted on [Mongo Atlas / local / etc.]).
Heroku / Render / other for deployment.
dotenv for environment variables.
If I had more time, I would add authentication, user profiles, and more thorough error handling. I’d also consider pagination or infinite scroll to handle large numbers of thoughts.

Endpoints
GET /thoughts
Returns the 20 most recent thoughts, sorted by creation date.
POST /thoughts
Creates a new thought given a valid message.
POST /thoughts/:id/like
Increments or toggles the like count of a specific thought by ID.

## View it live

Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about.
[Deployed API link](https://project-happy-thoughts-api-hc1b.onrender.com/) Click to see the available endpoints and try them out!
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
"@babel/node": "^7.16.8",
"@babel/preset-env": "^7.16.11",
"cors": "^2.8.5",
"dotenv": "^16.4.7",
"express": "^4.17.3",
"express-list-endpoints": "^7.1.1",
"mongoose": "^8.0.0",
"nodemon": "^3.0.1"
}
Expand Down
142 changes: 116 additions & 26 deletions server.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,117 @@
import cors from "cors";
import express from "express";
import mongoose from "mongoose";

const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/project-mongo";
mongoose.connect(mongoUrl);
mongoose.Promise = Promise;

// Defines the port the app will run on. Defaults to 8080, but can be overridden
// when starting the server. Example command to overwrite PORT env variable value:
// PORT=9000 npm start
const port = process.env.PORT || 8080;
const app = express();

// Add middlewares to enable cors and json body parsing
app.use(cors());
app.use(express.json());

// Start defining your routes here
app.get("/", (req, res) => {
res.send("Hello Technigo!");
});

// Start the server
import express from 'express'
import cors from 'cors'
import mongoose from 'mongoose'
import dotenv from 'dotenv'
import listEndpoints from 'express-list-endpoints'

dotenv.config()

// ----------------------
// 1. Mongoose Connection
// ----------------------
const MONGO_URL = process.env.MONGODB_URI || 'mongodb://127.0.0.1/happy-thoughts'
mongoose.connect(MONGO_URL);

// ----------------------
// 2. Mongoose Model
// ----------------------
const ThoughtSchema = new mongoose.Schema({
message: {
type: String,
required: true,
minlength: 5,
maxlength: 140
},
hearts: {
type: Number,
default: 0
},
likedUsers: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
],
createdAt: {
type: Date,
default: () => new Date()
}
})

const Thought = mongoose.model('Thought', ThoughtSchema)

// ----------------------
// 3. Express App Setup
// ----------------------
const app = express()
const port = process.env.PORT || 8080

app.use(cors({
origin: 'https://happiestthoughts.netlify.app',
methods: ['GET', 'POST'],
allowedHeaders: ['Content-Type', 'Authorization']
}))
app.use(express.json())

// ----------------------
// 4. Endpoints
// ----------------------

app.get('/', (req, res) => {
res.json({
message: 'Welcome to the Happy Thoughts API!',
endpoints: listEndpoints(app)
})
})

app.get('/thoughts', async (req, res) => {
try {
const thoughts = await Thought.find()
.sort({ createdAt: 'desc' })
.limit(20)
.exec()
res.status(200).json(thoughts)
} catch (err) {
res.status(500).json({ error: 'Could not fetch thoughts' })
}
})

app.post('/thoughts', async (req, res) => {
const { message } = req.body
try {
const newThought = new Thought({ message })
const savedThought = await newThought.save()
res.status(201).json(savedThought)
} catch (err) {
res.status(400).json({
error: 'Could not save thought',
details: err.errors
})
}
})

app.post('/thoughts/:id/like', async (req, res) => {
try {
const { id } = req.params

const updatedThought = await Thought.findByIdAndUpdate(
id,
{ $inc: { hearts: 1 } },
{ new: true }
)

if (!updatedThought) {
return res.status(404).json({ error: 'Thought not found' })
}

res.status(200).json(updatedThought)
} catch (err) {
res.status(500).json({ error: 'Could not update hearts' })
}
})

// ----------------------
// 5. Start the Server
// ----------------------
app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`);
});
})