diff --git a/README.md b/README.md index 6a75d8e1..ff857cfc 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,17 @@ # 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. +API to support the Happy Thoughts Project. Serve get requests and handle post request by querying a mongo database. ## 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 set up a connection to a database, MongoDB, and added endpoints needed to support the Happy Thoughts frontend using Express. Changed url in frontend to point to new server. + +Further on I would like to try out and add more features like pagination and allowing the user to either be anonymous or to enter their name when they post their happy thought. ## 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. +Backend: +https://project-happy-thoughts-api-rn3z.onrender.com + +Frontend: +https://happy-thoughts-fms.netlify.app/ diff --git a/models/ThoughtSchema.js b/models/ThoughtSchema.js new file mode 100644 index 00000000..69c2e31a --- /dev/null +++ b/models/ThoughtSchema.js @@ -0,0 +1,24 @@ +import mongoose from "mongoose"; + +const { Schema } = mongoose; + +export const ThoughtSchema = new Schema({ + message: { + type: String, + required: true, + minlength: 5, + maxlength: 140, + }, + hearts: { + type: Number, + default: 0, + }, + createdAt: { + type: Date, + default: Date.now, + }, +}); + +// Mongoose model +const Thought = mongoose.model("Thought", ThoughtSchema); +export default Thought; diff --git a/package.json b/package.json index 1c371b45..c6a59c4b 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,10 @@ "@babel/node": "^7.16.8", "@babel/preset-env": "^7.16.11", "cors": "^2.8.5", + "dotenv": "^16.4.5", "express": "^4.17.3", + "express-list-endpoints": "^7.1.0", "mongoose": "^8.0.0", "nodemon": "^3.0.1" } -} \ No newline at end of file +} diff --git a/server.js b/server.js index dfe86fb8..1d9d944d 100644 --- a/server.js +++ b/server.js @@ -1,8 +1,16 @@ import cors from "cors"; import express from "express"; import mongoose from "mongoose"; +import dotenv from "dotenv"; +import expressListEndpoints from "express-list-endpoints"; +import Thought from "./models/ThoughtSchema"; -const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/project-mongo"; +// Load environment variables +dotenv.config(); + +// Set up mongoURL and localhost +const mongoUrl = + process.env.MONGO_URL || "mongodb://localhost/happy-thoughts-api"; mongoose.connect(mongoUrl); mongoose.Promise = Promise; @@ -12,13 +20,86 @@ mongoose.Promise = Promise; const port = process.env.PORT || 8080; const app = express(); -// Add middlewares to enable cors and json body parsing +// ---- MIDDLEWARES ---- + +// Middlewares to enable cors and json body parsing app.use(cors()); app.use(express.json()); +// Middleware to check database status +app.use((req, res, next) => { + if (mongoose.connection.readyState === 1) { + next(); + } else { + res.status(503).json({ error: "Service unavailable" }); + } +}); + +// ---- ROUTES ---- -// Start defining your routes here +// GET API documentation app.get("/", (req, res) => { - res.send("Hello Technigo!"); + try { + const endpoints = expressListEndpoints(app); + res.json(endpoints); + } catch (error) { + console.error("Error", error); + res + .status(500) + .send("This page is unavailable at the moment. Please try again later."); + } +}); + +// GET thoughts +app.get("/thoughts", async (req, res) => { + const allThoughts = await Thought.find() + .sort({ createdAt: "desc" }) + .limit(20) + .exec(); + res.json(allThoughts); +}); + +// POST thought +app.post("/thoughts", async (req, res) => { + const { message } = req.body; + + try { + // Success case - create thought + const thought = await new Thought({ + message, + }).save(); + + // Set success status + res.status(201).json(thought); + } catch (error) { + // Failed case - return error message + res.status(400).json({ + sucess: false, + response: error, + message: "Unable to create thought", + }); + } +}); + +// POST like +app.post("/thoughts/:thoughtId/like", async (req, res) => { + const { thoughtId } = req.params; + + try { + const thought = await Thought.findById(thoughtId).exec(); + + if (thought) { + // Add one like + thought.hearts++; + // Save thought object + thought.save(); + res.json(thought); + } else { + res.status(404).send("Could not find thought"); + } + } catch (error) { + console.error("Error", error); + res.status(404).send("Could not find thought"); + } }); // Start the server