Backend for a full-stack travel memory application where users can save photo-based memories and attach them to real-world locations.
This repository is the backend portion of a larger school project. While the frontend was built collaboratively with Next.js, I designed and implemented the backend myself using Node.js, Express.js, and an Azure MySQL cloud database. I also helped connect parts of the frontend to the API layer I created.
- About
- Why This Project Matters
- Backend Highlights
- Architecture
- Data Model
- API Overview
- Tech Stack
- Running Locally
- What I Learned
Memory Server powers an app built to help travelers preserve memories by storing photos and linking them to specific places. The backend handles the application's core data flows:
- user registration, login, profile updates, and password reset
- creating and retrieving memories tied to map coordinates
- associating memories with collaborators
- attaching image URLs to memories
- updating and deleting related records across multiple tables
The project was especially important to me because it was my first full backend build. I used it to learn how to design a server from the ground up, structure a codebase with MVC principles, and expose RESTful endpoints that a frontend could reliably consume.
For portfolio purposes, this repository best represents my individual contribution to the overall application.
- I built the backend end-to-end rather than only contributing isolated tickets.
- I learned how to break application logic into
routes,controllers,services,models, andconfiguration. - I implemented CRUD-focused REST APIs for the app's main resources:
users,memories, collaborators, and images. - I integrated the backend with a cloud-hosted relational database on Azure, which gave me hands-on experience working beyond a local-only setup.
- I worked on the contract between frontend and backend by helping wire some API usage from the client side.
The codebase follows an MVC-inspired structure:
routes/defines HTTP endpointscontrollers/handles request/response flowservices/contains business logic and database operationsmodels/shapes application dataconfig/stores environment-driven database configuration
This separation made the project easier to reason about and gave me early experience designing maintainable server-side code.
The backend exposes endpoints under:
/api/users/api/memories
These endpoints support creating, reading, updating, and deleting application data, including more specific actions such as:
- retrieving memories created by a specific user
- retrieving memories a user collaborated on
- updating memory location, title, and privacy settings
- adding and removing collaborators
- adding and removing image references
The memory feature is modeled across multiple related tables rather than a single flat object. A memory can include:
- a creator
- a title
- privacy state
- longitude and latitude
- many collaborators
- many image URLs
That required thinking through one-to-many style relationships and how to reconstruct useful API responses from normalized database records.
Creating and deleting memories is more than a single insert or delete. The backend coordinates changes across memory, collaborator, and image tables, including transaction-based flows for related inserts. Building that logic helped me understand how backend systems maintain consistency across connected records.
The project is intentionally lightweight and centered around Express, but still structured like a real backend service:
server.js
config/
controllers/
models/
routes/
services/
database_general/
memories/
users/
- A client sends a request to an Express route.
- The route forwards the request to a controller.
- The controller validates/extracts inputs and calls a service function.
- The service performs business logic and database operations.
- A JSON response is returned to the frontend.
This project gave me practical experience thinking in layers instead of writing everything in a single file.
At a high level, the backend manages these concepts:
- account creation
- login lookup
- profile editing
- password reset
- creator ID
- memory name/title
- privacy flag
- latitude and longitude
- links a user to a memory
- allows a memory to be shared with multiple people
- stores image URLs associated with a memory
- allows multiple images per memory
This structure let me represent richer user interactions than basic single-table CRUD.
POST /api/users/registerGET /api/users/loginPUT /api/users/editDELETE /api/users/removeGET /api/users/:idGET /api/users/PUT /api/users/reset-password
POST /api/memories/addGET /api/memories/getAllByUserGET /api/memories/getAllWithCollaboratedByUserGET /api/memories/allGET /api/memories/:idPOST /api/memories/editLongitudeLatitudePOST /api/memories/editTitlePOST /api/memories/editIsPrivatePOST /api/memories/addCollaboratorsPOST /api/memories/addImagesDELETE /api/memories/removeCollaboratorsDELETE /api/memories/removeImagesDELETE /api/memories/removeMemory
Node.jsExpress.jsJavaScript (ES Modules)
MySQLAzure Database for MySQLmysql2
corsdotenv
- frontend built with
Next.js - backend in this repository built by me
Node.js- access to the project's environment variables
- access to the Azure MySQL instance used by the app
This project expects a .env file with values for:
DB_HOST_ADDRESSDB_USERNAMEDB_PASSWORDDATABASE_NAMEPORT
It also uses the SSL certificate located at:
config/DigiCertGlobalRootCA.crt.pem
npm install
npm startBy default, the server runs on the port defined in .env, or falls back to 5050.
This project helped me build foundational backend skills that I plan to keep growing:
- designing REST APIs that a frontend can integrate with
- structuring a backend with MVC-style separation of concerns
- working with a relational schema instead of only simple in-memory data
- handling multi-table create, update, and delete flows
- connecting a Node/Express backend to a cloud-hosted Azure MySQL database
- thinking about how backend responses should be shaped for frontend use
Because this was my first backend project, it was also where I learned how much thought goes into application structure, database design, and making sure different parts of a stack communicate clearly.