Lesson 1 of 8
Resumator — Project Planning & Setup
Estimated time: 2–2.5 hours
What You Will Learn
- Understand what the Resumator application does and why you are building it
- Plan the architecture of a full-stack Spring Boot application
- Set up a new Spring Boot project with the correct dependencies
- Create a MySQL database and user for the project
- Configure
application.propertiesfor database and API connectivity - Sign up for the JSearch API and securely store your API key
- Organize your project into a clean package structure
- Verify that your Spring Boot application starts without errors
Part 1 — Building Something Real
Welcome to the most exciting part of the Coders Farm curriculum. Over the next six lessons, you are going to build a real application that you will actually use in your job search. Not a toy project. Not a tutorial exercise. A genuine tool that searches for real job listings, lets you browse results, save your favorites, and manage your job search — all powered by a Spring Boot backend and a MySQL database.
This application is called Resumator. Think of it as your personal job search assistant. You have already learned how to build Spring Boot APIs (Lessons 11–15), and you just finished setting up MySQL (Lesson 22). Now it is time to combine everything you know into a cohesive, professional-grade application. Every skill you have built so far — HTML, CSS, JavaScript, Java, Spring Boot, SQL — comes together here.
Why a job search app? Because learning to code is only half the battle. You also need to find a job. Resumator solves both problems at once: you practice your development skills while building a tool that helps you land your first role. When you sit down for an interview and someone asks "What have you built?", you will have a real, working application to show them — one that demonstrates API integration, database management, full-stack architecture, and practical problem-solving.
In this first lesson, we are going to plan the entire project and set up the foundation. By the end of today, you will have a fully configured Spring Boot project connected to a MySQL database and ready to start accepting code. Think of this lesson as laying the foundation of a house — it is not the most glamorous part, but nothing else works without it.
Part 2 — What Resumator Does
Before we write a single line of code, let us clearly define what Resumator will do when it is finished. Professional developers always start by understanding the requirements before jumping into code. This is a habit worth building now.
Resumator Features
- Search for real jobs. You will type a job title (like "Java Developer" or "Software Engineer") and a city (like "Lansing, MI" or "Detroit, MI"), and Resumator will search for real, current job listings using the JSearch API.
- Browse results. The search results will be displayed in a clean, easy-to-read format showing the job title, company name, location, and a snippet of the description.
- Favorite listings. When you find a job that looks interesting, you can click a button to save it to your favorites. This saves the listing to your MySQL database so it persists even if you close the browser or restart the server.
- Manage saved jobs. You can view all of your saved jobs in one place, and remove any that you are no longer interested in.
That is the complete application. It may sound simple, but building it will teach you how real applications are structured. You will work with external APIs, handle HTTP requests and responses, manage a database, and build a frontend that ties it all together. These are the exact same skills you will use every day as a professional developer.
Part 3 — Architecture Overview
Every application has an architecture — a plan for how the different parts fit together. Before you start building, you need to understand the big picture. Resumator has three main components, and they talk to each other in a specific order.
When a user searches for jobs, the data flows like this:
Here is what happens step by step. The user types a search query into a form in their browser. The browser sends that query to your Spring Boot backend server. Your Spring Boot server then calls the JSearch API (an external job search service) with that query, receives the results, and passes them back to the browser for display. Your Spring Boot server acts as a middleman between the browser and the external API. This is a very common pattern in web development — your backend talks to external services on behalf of your frontend.
When a user favorites a job, the data flows differently:
The user clicks "Save" on a job listing in the browser. The browser sends the job data to your Spring Boot server. Your server then stores the job in your MySQL database. When the user wants to see their saved jobs, the flow reverses: Spring Boot reads from MySQL and sends the data back to the browser.
The Three Layers
- Frontend (Browser): HTML, CSS, and JavaScript that the user interacts with. Sends requests to your Spring Boot server.
- Backend (Spring Boot): Your Java application. Handles business logic, talks to external APIs, and manages the database. This is where most of your code lives.
- Data Layer (MySQL + JSearch): MySQL stores your persistent data (saved jobs). JSearch provides real-time job listings from across the internet.
Part 4 — Setting Up the Spring Boot Project
You have done this before in Lesson 12 when you created the contact-api project. The process is the same, but this time we are choosing different dependencies because Resumator has different needs. Head over to start.spring.io and configure the project with the following settings.
| Field | Value | What It Means |
|---|---|---|
| Project | Maven |
The build tool that manages your dependencies and compiles your code. Same as the contact-api project. |
| Language | Java |
The programming language for our backend code. |
| Spring Boot | Latest stable (3.4.x) | Avoid SNAPSHOT or pre-release versions. Pick the latest stable release. |
| Group | org.codersfarm |
Your organization identifier in reverse domain format. |
| Artifact | resumator |
The name of your project. This becomes the folder name and the jar file name. |
| Name | resumator |
A human-readable name for the project. |
| Description | Job search assistant for Coders Farm |
A brief description of what this project does. |
| Package name | org.codersfarm.resumator |
The base Java package. Auto-generated from Group and Artifact. |
| Packaging | Jar |
Standard packaging format for Spring Boot applications. |
| Java | 21 |
Java 21 LTS — the latest long-term support release. |
Now for the dependencies. Click "Add Dependencies" (or press Ctrl+B) and add the following three dependencies. Each one serves a specific purpose:
Dependencies Explained
-
Spring Web — This is the same dependency you used in the contact-api project. It gives you everything you need to build REST APIs: the embedded Tomcat web server, HTTP request handling, JSON serialization, and the
@RestControllerand@GetMappingannotations you already know. Without this, your application cannot serve web requests. - Spring Data JPA — JPA stands for Java Persistence API. This dependency lets your Java code talk to a database without writing raw SQL. You define Java classes that represent database tables, and Spring Data automatically generates the SQL queries for you. You saw this pattern briefly in Lesson 14 with SQLite. Now you will use it with MySQL.
- MySQL Driver — This is the JDBC driver that allows Java to communicate with MySQL. Think of it as a translator — your Java code speaks Java, MySQL speaks its own protocol, and the driver handles the translation between them. Without this driver, Spring Boot would not know how to connect to your MySQL database.
Double-check that all three dependencies are listed, then click "Generate". Download the resumator.zip file, unzip it, and open the resumator folder in your code editor (VS Code or IntelliJ IDEA). If you are using IntelliJ, it will detect the Maven project and begin downloading the dependencies automatically.
Once the project is open, take a quick look at the generated pom.xml file. You should see all three dependencies listed. Here is what the relevant section looks like:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Notice the <scope>runtime</scope> tag on the MySQL driver. This tells Maven that the driver is only needed when the application runs, not when compiling your code. This is because your code never directly references MySQL-specific classes — Spring Data JPA provides an abstraction layer. Also notice that Spring Boot included a test dependency automatically. You do not need to do anything with it right now, but it is there when you are ready to write tests.
Part 5 — Creating the MySQL Database
In Lesson 22, you installed MySQL and learned how to use the MySQL command-line client. Now you are going to create a dedicated database and user for Resumator. This is a best practice in professional development — every application gets its own database and its own database user with specific permissions. You never want your application connecting as the root user.
Open your terminal and connect to MySQL as the root user:
mysql -u root -p
Enter your root password when prompted. Once you are connected, run the following SQL commands one at a time:
CREATE DATABASE resumator;
CREATE USER 'resumator_app'@'localhost' IDENTIFIED BY 'your_password_here';
GRANT ALL PRIVILEGES ON resumator.* TO 'resumator_app'@'localhost';
FLUSH PRIVILEGES;
Let us break down each command:
CREATE DATABASE resumator;— Creates a new, empty database calledresumator. All of your application's tables will live inside this database.CREATE USER 'resumator_app'@'localhost' ...— Creates a new MySQL user namedresumator_appthat can only connect from your local machine (localhost). Replaceyour_password_herewith an actual password of your choosing. Write it down — you will need it in the next step.GRANT ALL PRIVILEGES ON resumator.* ...— Gives theresumator_appuser full access to theresumatordatabase, but only that database. This user cannot see or modify any other databases on your MySQL server.FLUSH PRIVILEGES;— Tells MySQL to reload the permission tables so the new user's access takes effect immediately.
You can verify everything worked by running these commands while still logged into MySQL:
SHOW DATABASES;
-- You should see "resumator" in the list
SELECT User, Host FROM mysql.user WHERE User = 'resumator_app';
-- You should see one row: resumator_app | localhost
Once you have confirmed the database and user exist, type exit; to leave the MySQL client.
Part 6 — Configuring application.properties
Now you need to tell Spring Boot how to connect to your MySQL database. Open the file src/main/resources/application.properties. This file is currently empty. Add the following configuration:
# ===== Database Configuration =====
spring.datasource.url=jdbc:mysql://localhost:3306/resumator
spring.datasource.username=resumator_app
spring.datasource.password=your_password_here
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# ===== JPA / Hibernate Configuration =====
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
# ===== Server Configuration =====
server.port=8080
# ===== JSearch API Configuration =====
jsearch.api.key=YOUR_API_KEY_HERE
jsearch.api.url=https://jsearch.p.rapidapi.com
Let us go through each section:
Database Configuration: The spring.datasource.url tells Spring Boot where to find your MySQL database. The format is jdbc:mysql://host:port/database_name. Since MySQL runs on your local machine on port 3306 (the default), and your database is called resumator, the URL is jdbc:mysql://localhost:3306/resumator. The username and password are the ones you created in the previous step. The driver class name tells Spring Boot which JDBC driver to use for the connection.
JPA / Hibernate Configuration: The spring.jpa.hibernate.ddl-auto=none setting tells Hibernate (the JPA implementation that Spring Boot uses) not to automatically create or modify your database tables. This means you will manage your database schema yourself. The spring.jpa.show-sql=true setting prints every SQL query that Hibernate generates to the console, which is incredibly helpful for learning and debugging. The dialect setting tells Hibernate that you are using MySQL so it generates MySQL-compatible SQL.
ddl-auto to update or create, which would make Hibernate automatically create database tables for you. We are intentionally setting it to none for now. Managing your database schema manually is an important skill, and we will walk through table creation step by step in a later lesson.
Server Configuration: The server.port=8080 sets the port that your embedded Tomcat server will listen on. Port 8080 is the Spring Boot default, so this line is technically optional, but it is good practice to be explicit about your configuration.
JSearch API Configuration: These are custom properties that you will read from your Java code. The jsearch.api.key will hold your RapidAPI key (we will set this up in the next section), and jsearch.api.url is the base URL for the JSearch API. Custom properties like these are a clean way to keep configuration values out of your Java code.
your_password_here with the actual password you chose when creating the MySQL user, and YOUR_API_KEY_HERE with your real API key (which you will get in the next section). These placeholder values will not work.
Part 7 — Signing Up for the JSearch API
Resumator searches for real job listings using an external service called JSearch, which is available through RapidAPI. RapidAPI is a marketplace where developers can discover and connect to thousands of APIs. JSearch aggregates job postings from across the internet — LinkedIn, Indeed, Glassdoor, and many more — and makes them available through a single, simple API.
The JSearch free tier gives you 500 requests per month, which is more than enough for development and personal use. Here is how to set it up:
- Create a RapidAPI account. Go to rapidapi.com and sign up for a free account. You can use your email or sign in with GitHub or Google.
-
Find JSearch. Once logged in, search for "JSearch" in the RapidAPI search bar. Click on the JSearch API by OpenWeb Ninja. You should see the API documentation page with endpoints like
/search,/search-filters, and/job-details. - Subscribe to the free tier. Click the "Pricing" tab and select the Basic (Free) plan. This gives you 500 requests per month at no cost. You may be asked to enter a credit card for verification, but you will not be charged on the free tier.
-
Get your API key. After subscribing, go back to the API's "Endpoints" tab. In the code snippets section on the right side, look for the header labeled
x-rapidapi-key. The value next to it is your API key — a long string of letters and numbers. Copy this key. -
Add the key to application.properties. Go back to your
application.propertiesfile and replaceYOUR_API_KEY_HEREwith the key you just copied.
- Add
src/main/resources/application.propertiesto your.gitignorefile so Git never tracks it. - Create a file called
application.properties.examplein the same folder with placeholder values (likeYOUR_API_KEY_HERE) so that other developers know what configuration is needed without seeing your actual secrets.
Let us add the .gitignore entry now. Open the .gitignore file in your project's root directory (Spring Initializr created one for you) and add this line at the bottom:
# Sensitive configuration
src/main/resources/application.properties
Then create a copy of your properties file as a template for other developers:
# ===== Database Configuration =====
spring.datasource.url=jdbc:mysql://localhost:3306/resumator
spring.datasource.username=resumator_app
spring.datasource.password=YOUR_DB_PASSWORD_HERE
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# ===== JPA / Hibernate Configuration =====
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
# ===== Server Configuration =====
server.port=8080
# ===== JSearch API Configuration =====
jsearch.api.key=YOUR_RAPIDAPI_KEY_HERE
jsearch.api.url=https://jsearch.p.rapidapi.com
Save this as src/main/resources/application.properties.example. This file is safe to commit to Git because it contains no real secrets — just placeholders that tell other developers what values they need to provide.
Part 8 — Project Package Structure
When you build a small project with one or two files, organization does not matter much. But as your application grows, you need a clear structure so you can find things quickly. Professional Spring Boot applications follow a standard package layout that separates code by responsibility. Here is the structure you are going to use for Resumator:
src/main/java/org/codersfarm/resumator/
ResumatorApplication.java <-- Main entry point (already generated)
controller/ <-- Handles HTTP requests
JobSearchController.java
FavoriteController.java
service/ <-- Business logic
JobSearchService.java
FavoriteService.java
model/ <-- Data structures (entities)
Job.java
FavoriteJob.java
repository/ <-- Database access
FavoriteJobRepository.java
Each package has a specific responsibility:
The Four-Package Pattern
-
controller— Controllers handle incoming HTTP requests and return responses. They are the "front door" of your application. When a browser sends a request to/api/jobs/search, a controller method receives it. Controllers should be thin — they receive the request, call a service to do the real work, and return the result. You already used this pattern withHelloControllerandContactControllerin earlier lessons. -
service— Services contain your business logic — the rules and processes that make your application actually do things. For example, theJobSearchServicewill call the JSearch API, parse the response, and transform it into Java objects. Putting this logic in a service (instead of directly in the controller) keeps your code organized and makes it easier to test. -
model— Models are plain Java classes that represent your data. AJobmodel might have fields liketitle,company,location, anddescription. When a model is also saved to the database, it is called an entity. YourFavoriteJobclass will be an entity because it maps to a MySQL table. -
repository— Repositories handle all database operations. Spring Data JPA makes this incredibly easy: you write a Java interface (not a class), and Spring automatically implements the database queries for you. YourFavoriteJobRepositorywill let you save, find, and delete favorite jobs with zero SQL.
This pattern is called layered architecture, and it is used by virtually every professional Spring Boot application. The flow always moves in one direction: Controller → Service → Repository → Database. Controllers never talk directly to the database, and repositories never handle HTTP requests. Each layer does one job and does it well.
For now, just create the empty package folders. In your src/main/java/org/codersfarm/resumator/ directory, create four new folders:
controllerservicemodelrepository
Part 9 — Verify Your Setup
It is time to make sure everything is wired up correctly. Open your terminal, navigate to the resumator project directory (the folder that contains pom.xml), and run the application:
Mac or Linux:
./mvnw spring-boot:run
Windows:
mvnw.cmd spring-boot:run
Watch the terminal output carefully. You are looking for a line like this near the end:
Started ResumatorApplication in X.XXX seconds
If you see that message, congratulations — your project is correctly configured and running. The Spring Boot embedded Tomcat server is live on port 8080, and your application has successfully connected to the MySQL database.
If you see errors instead, here are the most common issues and their fixes:
| Error Message | Likely Cause | Fix |
|---|---|---|
Access denied for user 'resumator_app' |
Wrong password in application.properties | Double-check the password matches what you used in the CREATE USER command |
Unknown database 'resumator' |
The database was not created | Log into MySQL as root and run CREATE DATABASE resumator; |
Communications link failure |
MySQL is not running | Start the MySQL service: sudo systemctl start mysql (Linux) or brew services start mysql (Mac) |
Port 8080 already in use |
Another application is using port 8080 | Stop the other application or change server.port in application.properties to 8081 |
Once the application starts successfully, press Ctrl+C in the terminal to stop it. Your foundation is solid and ready for the next lesson.
Quiz — Check Your Understanding
1. In Resumator's architecture, why does the browser send requests to your Spring Boot server instead of calling the JSearch API directly?
Correct answer: B. If the browser called the JSearch API directly, your API key would be visible in the browser's source code, which is a serious security risk. By routing requests through your Spring Boot backend, you keep the key hidden on the server and gain control over data transformation, caching, and error handling.
2. Which three dependencies did you add to the Resumator project?
Correct answer: B. Resumator needs Spring Web (for REST API endpoints and the embedded web server), Spring Data JPA (for database access without writing raw SQL), and MySQL Driver (so Java can communicate with your MySQL database).
3. In the four-package pattern, which package is responsible for making calls to the database?
Correct answer: D. The repository package is responsible for all database operations. In a layered architecture, the flow goes Controller → Service → Repository → Database. Controllers handle HTTP requests, services contain business logic, models define data structures, and repositories handle database access.
Lesson Summary
You accomplished a lot in this lesson. Let us recap everything you did:
- You learned what Resumator is: a job search assistant that searches for real jobs, lets you browse results, favorite listings, and manage saved jobs.
- You planned the architecture: Browser → Spring Boot → JSearch API for searching, and Browser → Spring Boot → MySQL for saving favorites.
- You created a new Spring Boot project at start.spring.io with three dependencies: Spring Web, Spring Data JPA, and MySQL Driver.
- You created a MySQL database called
resumatorand a dedicated user with the right permissions. - You configured application.properties with database connection settings, JPA configuration, and API credentials.
- You signed up for the JSearch API on RapidAPI and learned how to keep your API key secure.
- You organized your project into the four-package pattern: controller, service, model, and repository.
- You verified that the application starts without errors.
The foundation is laid. In the next lesson, you will bring Resumator to life by building the Job Search API — a set of endpoints that call the JSearch API and return real job listings. You will write your first service class, learn how to make HTTP calls from Spring Boot, and parse JSON responses. The real fun starts now.
Finished this lesson?