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
-pflag.
- 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:runmvnw spring-boot:runIf 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
IOUentity class that maps to the "ious" table and has the following fields:UUID idString borrowerString lenderBigDecimal amountInstant dateTime
- Ensure the
idfield is set as the primary key and values are generated using the appropriate strategy for aUUIDfield - 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
IOURepositoryinterface 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 NoSuchElementExceptionIOU createIOU(IOU iou) throws IllegalArgumentException, OptimisticLockingFailureExceptionIOU updateIOU(UUID id, IOU updatedIOU) throws NoSuchElementExceptionvoid deleteIOU(UUID id)
- Create an
IOUControllerclass 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
iouspackage 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
findByBorrowerthat accepts a stringborrowerparameter. - Create a method in your service class called
getIOUsByBorrower. - Extend the
getIOUSmethod of your controller to accept an optional query string parameter, e.g.:getIOUs(@RequestParam(required = false) String borrower) - Check the value of the
borrowerparameter 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
@Queryannotation that will return all IOUs with an above average value. Hint: create a subquery using theAVGfunction - Create a method in your service class called
getHighValueIOUs. - Create a
getHighValueIOUSmethod in your controller, mapped to the/highpath.
- Create a method in your repository interface called
- Test the new endpoint
- Commit your changes
- Create a new endpoint at
/lowto 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
idproperty 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! 🚀