A full stack web application that displays San Francisco food trucks and restaurants. Built with Java Spring Boot and React.
Backend
- Java 25
- Spring Boot 4.1.0
- Spring Data JPA
- H2 In-Memory Database
- Lombok
Note: This project uses Spring Boot 4.1.0 and Java 21 (downgraded from Java 25 for Railway deployment compatibility).
Frontend
- React 19
- Vite
- React Router DOM
- Axios
- View a list of 597 San Francisco food trucks loaded from CSV data
- Search food trucks by name
- Sort food trucks by name or address
- Click a food truck to view its details (name, address, food items, schedule)
- View live weather at each food truck's location
- Add new restaurants to the list
This application follows the MVC pattern:
| Layer | Role | Files |
|---|---|---|
| Model | Represents data and database structure | Restaurant.java |
| View | User interface the user interacts with | React frontend (/frontend/src) |
| Controller | Handles HTTP requests and routes them to the service layer | RestaurantController.java |
The Service layer (RestaurantService.java) sits between the Controller and the Model and contains all business logic, keeping the Controller thin and focused only on request/response handling.
A REST API built with Spring Boot exposes the following endpoints:
| Method | Endpoint | Operation |
|---|---|---|
| GET | /api/restaurants |
Read — fetch all restaurants |
| GET | /api/restaurants/{id} |
Read — fetch single restaurant |
| GET | /api/restaurants/search?query= |
Read — search by name |
| POST | /api/restaurants |
Create — add new restaurant |
| PUT | /api/restaurants/{id} |
Update — edit existing restaurant |
| DELETE | /api/restaurants/{id} |
Delete — remove restaurant |
This app integrates with the Open Meteo API (https://open-meteo.com) to fetch real-time weather data for each food truck's location. When a user views a food truck's detail page, the app uses the truck's latitude and longitude coordinates to call the Open Meteo API and display current temperature, wind speed, and weather conditions.
This integration lives in WeatherService.java and is exposed via the /api/restaurants/{id}/weather endpoint.
No API key is required - Open Meteo is fully free and open.
Encapsulation is demonstrated throughout the backend:
Restaurant.javaencapsulates all data fields as private with public getters/setters generated by Lombok's@DataannotationRestaurantRequest.java(DTO) encapsulates only the fields the frontend is allowed to send, separating external input from the internal data modelRestaurantService.javaencapsulates all business logic, hiding database implementation details from the controller
Abstraction is demonstrated via RestaurantRepository.java, which extends Spring Data JPA's JpaRepository. The repository interface declares method signatures like findAllByOrderByNameAsc() without implementing them — Spring generates the SQL automatically, abstracting away the database layer entirely.
foodbae/
├── backend/ # Java Spring Boot API
│ └── src/main/java/com/foodbae/backend/
│ ├── controller/ # REST API endpoints (C in MVC)
│ ├── service/ # Business logic
│ ├── repository/ # Database access layer
│ ├── model/ # Data objects (M in MVC)
│ ├── dto/ # Request/response objects
│ └── loader/ # CSV data seeder
│ └── src/main/resources/
│ ├── application.properties # App configuration
│ └── food_trucks.csv # Initial data (597 SF food trucks)
└── frontend/ # React application (V in MVC)
└── src/
├── api/ # Axios API calls
├── components/ # Reusable UI components
└── pages/ # Page-level components
- Java 25
- Node.js 18+
- Maven 3.x
cd backend
./mvnw spring-boot:runServer starts at http://localhost:8080
The database is seeded automatically from food_trucks.csv on startup.
You can inspect the database at http://localhost:8080/h2-console
- JDBC URL:
jdbc:h2:mem:foodbae - Username:
sa - Password: (leave blank)
cd frontend
npm install
npm run devApp runs at http://localhost:5173
Both backend and frontend must be running at the same time.
- Data is stored in an H2 in-memory database, so any restaurants added will reset when the backend restarts
- Schedule links are sourced from the City of SF permit system and may occasionally be unavailable