Build a RESTful API service that allows users to create
, read
, update
, and delete
IOUs (I Owe You) using Java and Spring Boot.
- Fork this repository in your GitHub account
- Clone your fork locally or open in CodeSpaces.
git clone [REPO_URL]
cd [REPO_NAME]
💡 Note: Replace [REPO_URL] with the link to your GitHub repository and [REPO_NAME] with the repository's name.
- Login to MySQL:
mysql -u root -p
💡 Note: If your root user doesn't have a password set, omit the
-p
flag.
- Create a new database:
CREATE DATABASE IF NOT EXISTS restapiexercise;
exit;
- Open this pre-configured Initializr project. Review the configured settings, but do not make any changes. Click "Generate" to download a zipped project.
- Ensure that your local repository is the current working directory in the terminal, then extract the downloaded zip file. IMPORTANT: Do NOT unzip the archive in (macOS) Finder or (Windows) Explorer as the extracted files won't be correctly positioned.
- macOS:
tar -xvf [download directory]/restapiexercise.zip --strip=1 -C .
, e.g.tar -xvf ~/Downloads/restapiexercise.zip --strip=1 -C .
- Git Bash:
unzip [download directory]/restapiexercise.zip -d /tmp/unzipped && mv /tmp/unzipped/restapiexercise/.[!.]* .
, e.g.unzip ~/Downloads/restapiexercise.zip -d /tmp/unzipped && mv /tmp/unzipped/restapiexercise/.[!.]* .
- Windows Command Prompt:
tar -xvf [download directory]\restapiexercise.zip --strip=1 -C %cd%
, e.g.tar -xvf %USERPROFILE%\Downloads\restapiexercise.zip --strip=1 -C %cd%
- macOS:
- Open your repository in VS Code
- Add the following values to src/main/resources/application.properties:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.open-in-view=true
spring.config.import=optional:./local.properties
- In order to prevent sensitive values from being committed to version control, add a new entry to the .gitignore file:
local.properties
- Create a new file at src/main/resources/local.properties and paste in the following:
spring.datasource.url=jdbc:mysql://localhost:3306/restapiexercise
# Replace "root" with your database user, if applicable
spring.datasource.username=root
# Specify your database user's password, if applicable. If your database user doesn't have a password set, delete the line below
spring.datasource.password=YOUR_MYSQL_PASSWORD
- Replace the username and password values with your MySQL credentials. IMPORTANT: Ensure there are no spaces before or after the password.
To start the API, run the following command:
./mvnw spring-boot:run
mvnw spring-boot:run
If successful, you should see output that ends similarly to the following:
2024-04-12T11:49:59.055-04:00 INFO 39975 --- [REST API Exercise] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path ''
2024-04-12T11:49:59.059-04:00 INFO 39975 --- [REST API Exercise] [ main] c.c.r.RestApiExerciseApplication : Started RestApiExerciseApplication in 1.493 seconds (process running for 1.638)
IMPORTANT: If everything is working correctly, the output will appear "stuck" and the command prompt won't return until you stop the application, which should now be running at http://localhost:8080/api/ious.
Stop the application by pressing Ctrl + C
- Create an ious package in the main restapiexercise package
- Create an
IOU
entity class that maps to the "ious" table and has the following fields:UUID id
String borrower
String lender
BigDecimal amount
Instant dateTime
- Ensure the
id
field is set as the primary key and values are generated using the appropriate strategy for aUUID
field - Define a constructor that accepts the following parameters:
IOU(String borrower, String lender, BigDecimal amount, Instant createdAt)
- Define a default (parameterless) constructor that calls the parameterised constructor internally. Consider what appropriate default values should be passed to the parameters
- Create getter and setter methods for each field, except
id
, which should only have a getter - Create an
IOURepository
interface that extendsListCrudRepository<IOU, UUID>
- If it's not already running, start your API with
./mvnw clean spring-boot:run
. Check the output and confirm there are no errors - Check your database contains an "ious" table with the correct columns and data types
- Create an IOUService class that accepts an IOURepository as a dependency and implements the following methods:
List<IOU> getAllIOUs()
IOU getIOU(UUID id) throws NoSuchElementException
IOU createIOU(IOU iou) throws IllegalArgumentException, OptimisticLockingFailureException
IOU updateIOU(UUID id, IOU updatedIOU) throws NoSuchElementException
void deleteIOU(UUID id)
- Create an
IOUController
class that implements the endpoints below. Ensure your service class is injected as a dependency and apply the appropriate annotations - Start your API and confirm there are no errors
Method | Endpoint | Description |
---|---|---|
GET | /api/ious | Retrieve a list of (optionally filtered) IOUs |
GET | /api/ious/{id} | Retrieve a specific IOU by its ID |
POST | /api/ious | Create a new IOU |
PUT | /api/ious/{id} | Update an existing IOU by ID |
DELETE | /api/ious/{id} | Delete an IOU by ID |
- Create an
ious
package inside the test/java/com/cbfacademy/restapiexercise package - Download the test suite and copy to the test ious package as IOUControllerTest.java
- Run the tests with
./mvnw test
- Examine the results. Which tests fail? What reasons are given?
- Create a new API endpoint to return IOUs for a specific borrower:
- Create a method in your repository interface called
findByBorrower
that accepts a stringborrower
parameter. - Create a method in your service class called
getIOUsByBorrower
. - Extend the
getIOUS
method of your controller to accept an optional query string parameter, e.g.:getIOUs(@RequestParam(required = false) String borrower)
- Check the value of the
borrower
parameter to determine whether to call the existing service method or the new, filtered, one
- Create a method in your repository interface called
- Test the modified endpoint
- Commit your changes
- Create a new API endpoint to return IOUs with above-average value:
- Create a method in your repository interface called
findHighValueIOUs
. - Define a native
@Query
annotation that will return all IOUs with an above average value. Hint: create a subquery using theAVG
function - Create a method in your service class called
getHighValueIOUs
. - Create a
getHighValueIOUS
method in your controller, mapped to the/high
path.
- Create a method in your repository interface called
- Test the new endpoint
- Commit your changes
- Create a new endpoint at
/low
to return IOUs that are below or equal to the average value. Implement the repository method using JPQL instead of SQL
You can test your endpoints using Postman or your preferred REST client at http://localhost:8080/api/ious
The JSON representation of an IOU that you'll get in responses or provide in the request body for POST
and PUT
requests will resemble the following:
{
"id": "d1415cfc-dbd9-4474-94fc-52e194e384fa",
"borrower": "John Doe",
"lender": "Alice Smith",
"amount": 100.0,
"dateTime": "2023-11-02T14:30:00Z"
}
💡 Note: Remember that the
id
property may not be needed for all request types.
- 📸 Commit frequently and use meaningful commit messages. A granular, well-labelled history becomes an increasingly valuable asset over time.
- 🌵 Use feature branches. Build the habit of isolating your changes for specific tasks and merging them into your default branch when complete.
- 🚦 Use consistent naming conventions. Choose easily understandable names and naming patterns for your classes, functions and variables.
- 📐 Keep your code tidy. Using the built-in formatting of VS Code or other IDEs makes your code easier to read and mistakes easier to spot.
- 📚 Read the docs. Whether via Intellisense in your IDE, or browsing online documentation, build a clear understanding of the libraries your code leverages.
- 📆 Don't wait until the last minute. Plan your work early and make the most of the time available to complete the assessment and avoid pre-deadline palpitations.
- 🆘 Ask. 👏 For. 👏 Help! 👏 Your mentors, instructors and assistants are literally here to support you, so make use of them - don't sit and struggle in silence.
Best of luck! Remember, it's not just about the destination; it's the journey. Happy coding! 🚀