In this project, we will build a Spring Boot application to serve as the backend for the 'Art Gallery' platform. 'Art Gallery' is a digital space where art enthusiasts can delve deep into the world of art pieces, their creators, and the galleries that showcase them.
Within 'Art Gallery', there are three key entities: Art
, Artist
, and Gallery
. The Art
entity establishes a Many-to-One relationship with the Artist
, signifying that an artist can create multiple art pieces, but each art piece is associated with a single artist. Additionally, the Artist
entity forms a Many-to-Many relationship with the Gallery
entity, indicating that an artist can exhibit their artworks in multiple galleries, and similarly, a gallery can showcase works from multiple artists.
**Implementation Files**
Use these files to complete the implementation:
ArtController.java
ArtRepository.java
ArtJpaService.java
ArtJpaRepository.java
Art.java
ArtistController.java
ArtistRepository.java
ArtistJpaService.java
ArtistJpaRepository.java
Artist.java
GalleryController.java
GalleryRepository.java
GalleryJpaService.java
GalleryJpaRepository.java
Gallery.java
Create a database that contains four tables art
, artist
, gallery
, and artist_gallery
using the given database schema.
You can refer to this session, for creating a database.
Create the SQL files and compose accurate queries to run the application. Inaccurate SQL files will result in test case failures.
**Database Schema**
Columns | Type |
---|---|
id | INTEGER (Primary Key, Auto Increment) |
name | TEXT |
genre | TEXT |
Columns | Type |
---|---|
id | INTEGER (Primary Key, Auto Increment) |
title | TEXT |
theme | TEXT |
artistId | INTEGER (Foreign Key) |
Columns | Type |
---|---|
id | INTEGER (Primary Key, Auto Increment) |
name | TEXT |
location | TEXT |
Columns | Type |
---|---|
artistId | INTEGER (Foreign Key) |
galleryId | INTEGER (Foreign Key) |
The columns artistId
and galleryId
can be combinedly declared as Primary Keys.
You can use the given sample data to populate the tables.
**Sample Data**
id | name | genre |
---|---|---|
1 | Leonardo da Vinci | Renaissance |
2 | Vincent van Gogh | Post-Impressionism |
3 | Pablo Picass | Cubism |
4 | Edward Hopper | American Modernism |
id | title | theme | artistId |
---|---|---|---|
1 | The Flight Study | Studies of Bird Wings | 1 |
2 | Mona Lisa 2.0 | Renaissance Portrait | 1 |
3 | Starry Countryside | Night Landscape | 2 |
4 | Sunflower Impressions | Floral | 2 |
5 | Cubist Self-Portrait | Abstract Portrait | 3 |
6 | Barcelona Abstracted | City Landscape | 3 |
7 | Downtown Solitude | Urban Scene | 4 |
8 | Night Cafe Redux | Modernist Interior | 4 |
id | name | location |
---|---|---|
1 | Louvre Museum | Paris |
2 | Van Gogh Museum | Amsterdam |
3 | Museo Picasso | Barcelona |
4 | Whitney Museum of American Art | New York |
artistId | galleryId |
---|---|
1 | 1 |
1 | 2 |
2 | 2 |
3 | 3 |
3 | 4 |
4 | 4 |
Use only art
, artist
, gallery
, and artist_gallery
as the table names in your code.
-
Artist.java
: TheArtist
class should contain the following attributes.Attribute Type artistId int artistName String genre String galleries List<Gallery> -
ArtistRepository.java
: Create aninterface
containing the required methods. -
ArtistJpaService.java
: Update the service class with logic for managing artist data. -
ArtistController.java
: Create the controller class to handle HTTP requests. -
ArtistJpaRepository.java
: Create an interface that implements theJpaRepository
interface. -
Art.java
: TheArt
class should contain the following attributes.Attribute Type artId int artTitle String theme String artist Artist -
ArtRepository.java
: Create aninterface
containing the required methods. -
ArtJpaService.java
: Update the service class with logic for managing art data. -
ArtController.java
: Create the controller class to handle HTTP requests. -
ArtJpaRepository.java
: Create an interface that implements theJpaRepository
interface. -
Gallery.java
: TheGallery
class should contain the following attributes.Attribute Type galleryId int galleryName String location String artists List<Artist> -
GalleryRepository.java
: Create aninterface
containing the required methods. -
GalleryJpaService.java
: Update the service class with logic for managing gallery data. -
GalleryController.java
: Create the controller class to handle HTTP requests. -
GalleryJpaRepository.java
: Create an interface that implements theJpaRepository
interface.
Implement the following APIs.
**API 1: GET /galleries**
Returns a list of all galleries in the gallery
table.
[
{
"galleryId": 1,
"galleryName": "Louvre Museum",
"location": "Paris",
"artists": [
{
"artistId": 1,
"artistName": "Leonardo da Vinci",
"genre": "Renaissance"
}
]
},
...
]
**API 2: POST /galleries**
Creates a new gallery in the gallery
table. Also, create an association between the gallery and artists in the artist_gallery
table based on the artistId
s provided in the artists
field. The galleryId
is auto-incremented.
{
"galleryName": "National Museum of Women in the Arts",
"location": "Washington DC",
"artists": [
{
"artistId": 4
}
]
}
{
"galleryId": 5,
"galleryName": "National Museum of Women in the Arts",
"location": "Washington DC",
"artists": [
{
"artistId": 4,
"artistName": "Georgia O’Keeffe",
"genre": "American Modernism"
}
]
}
**API 3: GET /galleries/{galleryId}**
Returns a gallery based on the galleryId
. If the given galleryId
is not found in the gallery
table, raise ResponseStatusException
with HttpStatus.NOT_FOUND
.
{
"galleryId": 1,
"galleryName": "Louvre Museum",
"location": "Paris",
"artists": [
{
"artistId": 1,
"artistName": "Leonardo da Vinci",
"genre": "Renaissance"
}
]
}
**API 4: PUT /galleries/{galleryId}**
Updates the details of a gallery based on the galleryId
and returns the updated gallery details. Also update the associations between the gallery and artists, if the artists
field is provided. If the given galleryId
is not found in the gallery
table, raise ResponseStatusException
with HttpStatus.NOT_FOUND
.
{
"location": "Washington, D.C.",
"artists": []
}
{
"galleryId": 5,
"galleryName": "National Museum of Women in the Arts",
"location": "Washington, D.C.",
"artists": []
}
**API 5: DELETE /galleries/{galleryId}**
Deletes a gallery from the gallery
table and its associations from the artist_gallery
table based on the galleryId
and returns the status code 204
(raise ResponseStatusException
with HttpStatus.NO_CONTENT
). If the given galleryId
is not found in the gallery
table, raise ResponseStatusException
with HttpStatus.NOT_FOUND
.
**API 6: GET /galleries/{galleryId}/artists**
Returns all artists associated with the gallery based on the galleryId
. If the given galleryId
is not found in the gallery
table, raise ResponseStatusException
with HttpStatus.NOT_FOUND
.
[
{
"artistId": 1,
"artistName": "Leonardo da Vinci",
"genre": "Renaissance",
"galleries": [
{
"galleryId": 1,
"galleryName": "Louvre Museum",
"location": "Paris"
},
{
"galleryId": 2,
"galleryName": "Van Gogh Museum",
"location": "Amsterdam"
}
]
}
]
**API 7: GET /galleries/artists**
Returns a list of all artists in the artist
table.
[
{
"artistId": 1,
"artistName": "Leonardo da Vinci",
"genre": "Renaissance",
"galleries": [
{
"galleryId": 1,
"galleryName": "Louvre Museum",
"location": "Paris"
},
{
"galleryId": 2,
"galleryName": "Van Gogh Museum",
"location": "Amsterdam"
}
]
},
...
]
**API 8: POST /galleries/artists**
Creates a new artist in the artist
table, if all the galleryId
s in the galleries
field exist in the gallery
table. Also, create an association between the artist and galleries in the artist_gallery
table. The artistId
is auto-incremented. If any given galleryId
is not found in the gallery
table, raise ResponseStatusException
with HttpStatus.BAD_REQUEST
.
{
"artistName": "Frida Kahlo",
"genre": "Surrealism",
"galleries": [
{
"galleryId": 4
}
]
}
{
"artistId": 5,
"artistName": "Frida Kahlo",
"genre": "Surrealism",
"galleries": [
{
"galleryId": 4,
"galleryName": "Whitney Museum of American Art",
"location": "New York"
}
]
}
**API 9: GET /galleries/artists/{artistId}**
Returns an artist based on the artistId
. If the given artistId
is not found in the artist
table, raise ResponseStatusException
with HttpStatus.NOT_FOUND
.
{
"artistId": 1,
"artistName": "Leonardo da Vinci",
"genre": "Renaissance",
"galleries": [
{
"galleryId": 1,
"galleryName": "Louvre Museum",
"location": "Paris"
},
{
"galleryId": 2,
"galleryName": "Van Gogh Museum",
"location": "Amsterdam"
}
]
}
**API 10: PUT /galleries/artists/{artistId}**
Updates the details of an artist based on the artistId
and returns the updated artist details. Also update the associations between the artist and galleries, if the galleries
field is provided. If the given artistId
is not found in the artist
table, raise ResponseStatusException
with HttpStatus.NOT_FOUND
. If any given galleryId
is not found in the gallery
table, raise ResponseStatusException
with HttpStatus.BAD_REQUEST
.
{
"galleries": [
{
"galleryId": 5
}
]
}
{
"artistId": 5,
"artistName": "Frida Kahlo",
"genre": "Surrealism",
"galleries": [
{
"galleryId": 5,
"galleryName": "National Museum of Women in the Arts",
"location": "Washington, D.C."
}
]
}
**API 11: DELETE /galleries/artists/{artistId}**
Deletes an artist from the artist
table based on the artistId
and returns the status code 204
(raise ResponseStatusException
with HttpStatus.NO_CONTENT
). Also, remove the association with the arts by keeping a null value in the art
table.
If the given artistId
is not found in the artist
table, raise ResponseStatusException
with HttpStatus.NOT_FOUND
.
{
"artId": 1,
"artTitle": "The Flight Study",
"theme": "Studies of Bird Wings",
"artist": null
}
**API 12: GET /artists/{artistId}/arts**
Returns all arts associated with the artist based on the artistId
. If the given artistId
is not found in the artist
table, raise ResponseStatusException
with HttpStatus.NOT_FOUND
.
[
{
"artId": 1,
"artTitle": "The Flight Study",
"theme": "Studies of Bird Wings",
"artist": {
"artistId": 1,
"artistName": "Leonardo da Vinci",
"genre": "Renaissance",
"galleries": [
{
"galleryId": 1,
"galleryName": "Louvre Museum",
"location": "Paris"
},
{
"galleryId": 2,
"galleryName": "Van Gogh Museum",
"location": "Amsterdam"
}
]
}
},
{
"artId": 2,
"artTitle": "Mona Lisa 2.0",
"theme": "Renaissance Portrait",
"artist": {
"artistId": 1,
"artistName": "Leonardo da Vinci",
"genre": "Renaissance",
"galleries": [
{
"galleryId": 1,
"galleryName": "Louvre Museum",
"location": "Paris"
},
{
"galleryId": 2,
"galleryName": "Van Gogh Museum",
"location": "Amsterdam"
}
]
}
}
]
**API 13: GET /artists/{artistId}/galleries**
Returns all galleries associated with the artist based on the artistId
. If the given artistId
is not found in the artist
table, raise ResponseStatusException
with HttpStatus.NOT_FOUND
.
[
{
"galleryId": 1,
"galleryName": "Louvre Museum",
"location": "Paris",
"artists": [
{
"artistId": 1,
"artistName": "Leonardo da Vinci",
"genre": "Renaissance"
}
]
},
{
"galleryId": 2,
"galleryName": "Van Gogh Museum",
"location": "Amsterdam",
"artists": [
{
"artistId": 1,
"artistName": "Leonardo da Vinci",
"genre": "Renaissance"
},
{
"artistId": 2,
"artistName": "Vincent van Gogh",
"genre": "Post-Impressionism"
}
]
}
]
**API 14: GET /galleries/artists/arts**
Returns a list of all arts in the art
table.
[
{
"artId": 1,
"artTitle": "The Flight Study",
"theme": "Studies of Bird Wings",
"artist": {
"artistId": 1,
"artistName": "Leonardo da Vinci",
"genre": "Renaissance",
"galleries": [
{
"galleryId": 1,
"galleryName": "Louvre Museum",
"location": "Paris"
},
{
"galleryId": 2,
"galleryName": "Van Gogh Museum",
"location": "Amsterdam"
}
]
}
},
...
]
**API 15: POST /galleries/artists/arts**
Creates a new art in the art
table and create an association between the art and the artist based on the id
of the artist
field. The artId
is auto-incremented.
{
"artTitle": "Downtown",
"theme": "Urban",
"artist": {
"artistId": 3
}
}
{
"artId": 7,
"artTitle": "Downtown",
"theme": "Urban",
"artist": {
"artistId": 3,
"artistName": "Pablo Picasso",
"genre": "Cubism",
"galleries": [
{
"galleryId": 3,
"galleryName": "Museo Picasso",
"location": "Barcelona"
},
{
"galleryId": 4,
"galleryName": "Whitney Museum of American Art",
"location": "New York"
}
]
}
}
**API 16: GET /galleries/artists/arts/{artId}**
Returns an art based on the artId
. If the given artId
is not found in the art
table, raise ResponseStatusException
with HttpStatus.NOT_FOUND
.
{
"artId": 1,
"artTitle": "The Flight Study",
"theme": "Studies of Bird Wings",
"artist": {
"artistId": 1,
"artistName": "Leonardo da Vinci",
"genre": "Renaissance",
"galleries": [
{
"galleryId": 1,
"galleryName": "Louvre Museum",
"location": "Paris"
},
{
"galleryId": 2,
"galleryName": "Van Gogh Museum",
"location": "Amsterdam"
}
]
}
}
**API 17: PUT /galleries/artists/arts/{artId}**
Updates the details of an art based on the artId
and returns the updated art details. If the id
in the artist
field is provided, update the association between the art and the artist based on the id
. If the given artId
is not found in the art
table, raise ResponseStatusException
with HttpStatus.NOT_FOUND
.
{
"artTitle": "Downtown Solitude",
"theme": "Urban Scene",
"artist": {
"artistId": 4
}
}
{
"artId": 7,
"artTitle": "Downtown Solitude",
"theme": "Urban Scene",
"artist": {
"artistId": 4,
"artistName": "Edward Hopper",
"genre": "American Modernism",
"galleries": [
{
"galleryId": 4,
"galleryName": "Whitney Museum of American Art",
"location": "New York"
}
]
}
}
**API 18: DELETE /galleries/artists/arts/{artId}**
Deletes an art from the art
table based on the artId
and returns the status code 204
(raise ResponseStatusException
with HttpStatus.NO_CONTENT
). If the given artId
is not found in the art
table, raise ResponseStatusException
with HttpStatus.NOT_FOUND
.
**API 19: GET /arts/{artId}/artist**
Returns the artist of art based on the artId
. If the given artId
is not found in the art
table, raise ResponseStatusException
with HttpStatus.NOT_FOUND
.
{
"artistId": 1,
"artistName": "Leonardo da Vinci",
"genre": "Renaissance",
"galleries": [
{
"galleryId": 1,
"galleryName": "Louvre Museum",
"location": "Paris"
},
{
"galleryId": 2,
"galleryName": "Van Gogh Museum",
"location": "Amsterdam"
}
]
}
Do not modify the code in ArtGalleryApplication.java