This demonstration API was written as part of the Northcoders Java Software Development bootcamp.
The purpose of this challenge was to demonstrate the development of a backend API and database for an imaginary record shop. The high-level requirements of the API were to allow a user to:
- Store information about the records they have in stock
- Query this data in various ways
- Update it accordingly
The criteria set for the challenge were:
- Create API endpoints with the appropriate HTTP verbs
- Name API base URL and endpoints appropriately
- Write production-quality code - good separation of concerns, clean and readable
- Practise test-driven development - good coverage of unit tests
- Include a descriptive README to document the key features of your solution, your assumptions, approaches and future thoughts.
- Apply error and exception handling considerations in your API design
- Include a
/health
endpoint to give the health of the application
The MVP for the challenge was to offer the following features:
- List all albums in stock
- Get album by id
- Add new albums into the database
- Update album details
- Delete albums from the database
This application was written in Java 21 using:
- Object-oriented programming paradigm
- Model–view–controller (MVC) design pattern
- Test-driven development methodology
- Java 21
- Maven 3.6.3 or higher
- Spring Boot 3.3.4 or higher
Optional:
- PostgreSQL
- AWS-RDS
- PgAdmin
- Postman
- Clone the Repository
git clone https://github.com/liam-ohara/record_shop_challenge.git
- Application.properties
Create the following .properties files under resources folder : src/main/resources/
application.properties
spring.application.name=recordshop spring.profiles.active=h2 springdoc.swagger-ui.path=/api/v1/swagger-ui.html management.endpoints.enabled-by-default=false management.endpoint.health.enabled=true management.endpoints.web.exposure.include=health
Create the following .properties file if using H2 database (non-persistent) and set
spring.profiles.active=h2
in your application.properties file:
application-h2.properties
spring.datasource.url=jdbc:h2:mem:recordshopdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password=password spring.jpa.hibernate.ddl-auto=update
##Enable H2 Console (optional, for debugging)
spring.h2.console.enabled=true spring.h2.console.path=/h2-console
Create the following .properties file if using PostgreSQL database and set
spring.profiles.active=localDB
in your application.properties file:
application-localDB.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/recordshop spring.datasource.username=postgres spring.datasource.password=postgres spring.jpa.database=postgresql spring.jpa.hibernate.ddl-auto=update
Create the following .properties file if using AWS-RDS and set spring.profiles.active=rds
in your application.properties file
application-rds.properties
spring.datasource.url=jdbc:postgresql://YOUR_AWS_RDS_URL/DATABASE_NAME spring.datasource.username=YOUR_DATABASE_NAME spring.datasource.password=YOUR_DATABASE_PASSWORD spring.jpa.database=postgresql spring.jpa.hibernate.ddl-auto=update
- Once the previous two steps are completed you may run the application
You can use Postman/Swagger to test the endpoints. To access Swagger open link in web after running the application.
http://localhost:8080/api/v1/swagger-ui/index.html
You may use PgAdmin if using PostgreSQL or AWS-RDS. To access H2 console open link in the web after running the application.
http://localhost:8080/h2-console/
BASE_URL: /api/v1/
-
Health endpoint: http://localhost:8080/actuator/health
-
Album: /api/v1/album
-
GET: getAllAlbums
http://localhost:8080/api/v1/album
[
{
"albumId": 1,
"name": "All Around My Hat",
"artist": {
"artistId": 1,
"name": "Steeleye Span"
},
"publisher": {
"publisherId": 1,
"name": "Air Studios"
},
"releaseDate": "1977-10-01",
"genre": "FOLK"
}
]
- GET: getAlbumById
http://localhost:8080/api/v1/album/1
[
{
"albumId": 1,
"name": "All Around My Hat",
"artist": {
"artistId": 1,
"name": "Steeleye Span"
},
"publisher": {
"publisherId": 1,
"name": "Air Studios"
},
"releaseDate": "1977-10-01",
"genre": "FOLK"
}
]
- GET: getAlbumsByArtistName
http://localhost:8080/api/v1/album/artist/Steeleye%20Span
[
{
"albumId": 1,
"name": "All Around My Hat",
"artist": {
"artistId": 1,
"name": "Steeleye Span"
},
"publisher": {
"publisherId": 1,
"name": "Air Studios"
},
"releaseDate": "1977-10-01",
"genre": "FOLK"
}
]
- GET: getAlbumsByAlbumName
http://localhost:8080/api/v1/album/albumname/All%20Around%20My%20Hat
[
{
"albumId": 1,
"name": "All Around My Hat",
"artist": {
"artistId": 1,
"name": "Steeleye Span"
},
"publisher": {
"publisherId": 1,
"name": "Air Studios"
},
"releaseDate": "1977-10-01",
"genre": "FOLK"
}
]
- GET: getAlbumsByReleaseYear
http://localhost:8080/api/v1/album/releaseyear/1977
[
{
"albumId": 1,
"name": "All Around My Hat",
"artist": {
"artistId": 1,
"name": "Steeleye Span"
},
"publisher": {
"publisherId": 1,
"name": "Air Studios"
},
"releaseDate": "1977-10-01",
"genre": "FOLK"
}
]
- GET: getAlbumsByGenre
http://localhost:8080/api/v1/album/genre/folk
[
{
"albumId": 1,
"name": "All Around My Hat",
"artist": {
"artistId": 1,
"name": "Steeleye Span"
},
"publisher": {
"publisherId": 1,
"name": "Air Studios"
},
"releaseDate": "1977-10-01",
"genre": "FOLK"
}
]
-
POST: insertAlbum
http://localhost:8080/api/v1/albumJSON format for request body:
{
"name":"All Around My Hat",
"artist":{"name":"Steeleye Span"},
"publisher":{"name":"Air Studios"},
"releaseDate":[1977,10,1],
"genre":"FOLK"
}
-
DELETE: deleteAlbum
http://localhost:8080/api/v1/album/1Returns JSON of the album deleted
[
{
"albumId": 1,
"name": "All Around My Hat",
"artist": {
"artistId": 1,
"name": "Steeleye Span"
},
"publisher": {
"publisherId": 1,
"name": "Air Studios"
},
"releaseDate": "1977-10-01",
"genre": "FOLK"
}
]
-
PUT: replaceAlbum
http://localhost:8080/api/v1/album/1Replaces the album with given id, with the album in the request body
JSON format for request body:
{
"name":"Computerwelt",
"artist":{"name":"Kraftwerk"},
"publisher":{"name":"Kling Klang"},
"releaseDate":[1981,2,11],
"genre":"ELECTRONIC"
}
-
PATCH: updateAlbum
http://localhost:8080/api/v1/album/1Updates the album with given id, with details provided in the request body
JSON format for request body:
{
"artist": {"name":"KraftWerk"}
}