- GET: Movie Search
- GET: Movie Search By Person Id
- GET: Movie Get By Movie Id
- GET: Person Search
- GET: Person Get By Person Id
Our application depends on a lot of files and resources to be able to run correctly. These files have been provided for you and are listed here for your reference. These files should NEVER be modified and must be left AS IS.
Maven gets all its settings from a file called pom.xml
. This file determines the dependencies we will use in our project as well as the plugins we use for compiling, testing, building, ect..
Spring Boot has a large number of settings that can be set with a file called application.yml
. We have already created this file for you and have filled it with some settings. There is a file for the main application as well as one for the tests.
There are two folders in this project that contain resources, and application settings, as well as files required for the tests.
There is a Single class that contain all of our test cases:
đź—„ movies |
---|
đź’ľ movies.genre | ||
---|---|---|
Column Name | Type | Attributes |
id | INT |
NOT NULL PRIMARY KEY |
name | VARCHAR(32) |
NOT NULL |
đź’ľ movies.person | ||
---|---|---|
Column Name | Type | Attributes |
id | INT |
NOT NULL PRIMARY KEY |
name | VARCHAR(128) |
NOT NULL |
birthday | DATE |
NULL |
biography | VARCHAR(8192) |
NULL |
birthplace | VARCHAR(128) |
NULL |
popularity | DECIMAL |
NULL |
profile_path | VARCHAR(32) |
NULL |
đź’ľ movies.movie | ||
---|---|---|
Column Name | Type | Attributes |
id | INT |
NOT NULL PRIMARY KEY |
title | VARCHAR(128) |
NOT NULL |
year | INT |
NOT NULL |
director_id | INT |
NOT NULL |
rating | DECIMAL |
NOT NULL DEFAULT 0.0 |
num_votes | INT |
NOT NULL DEFAULT 0 |
budget | BIGINT |
NULL |
revenue | BIGINT |
NULL |
overview | VARCHAR(8192) |
NULL |
backdrop_path | VARCHAR(32) |
NULL |
poster_path | VARCHAR(32) |
NULL |
hidden | BOOLEAN |
NOT NULL DEFAULT FALSE |
Constraints | ||
FOREIGN KEY (director_id) REFERENCES movies.person (id) ON UPDATE CASCADE ON DELETE RESTRICT |
đź’ľ movies.movie_person | ||
---|---|---|
Column Name | Type | Attributes |
movie_id | INT |
NOT NULL |
person_id | INT |
NOT NULL |
Constraints | ||
PRIMARY KEY (movie_id, person_id) |
||
FOREIGN KEY (movie_id) REFERENCES movies.movie (id) ON UPDATE CASCADE ON DELETE CASCADE |
||
FOREIGN KEY (person_id) REFERENCES movies.person (id) ON UPDATE CASCADE ON DELETE CASCADE |
đź’ľ movies.movie_genre | ||
---|---|---|
Column Name | Type | Attributes |
movie_id | INT |
NOT NULL |
genre_id | INT |
NOT NULL |
Constraints | ||
PRIMARY KEY (movie_id, genre_id) |
||
FOREIGN KEY (movie_id) REFERENCES movies.movie (id) ON UPDATE CASCADE ON DELETE CASCADE |
||
FOREIGN KEY (genre_id) REFERENCES movies.genre (id) ON UPDATE CASCADE ON DELETE RESTRICT |
All the data to initialize your database is found in the db
folder here: db folder. They are numbered in the order they should be executed.
All âť— 400: Bad Request
Results must be checked first, and returned before any other action is made.
The order of the checks within âť— 400: Bad Request
is not tested as each Result is tested individually.
In the case of non-successful results, where values are expected, the values should not be included, for example.
{
"result": {
"code": 32,
"message": "Data contains invalid integers"
},
"value": null
}
the value
key should not be included:
{
"result": {
"code": 32,
"message": "Data contains invalid integers"
}
}
This is done by insuring that all null
values are dropped by either:
- Having your Model extend
ResponseModel<Model>
, or - Putting the
@JsonInclude(JsonInclude.Include.NON_NULL)
on your Model class
All Result
objects are available as static constants inside of the com.github.klefstad_teaching.cs122b.core.result.MoviesResults
class.
These can be used rather than creating your own.
All endpoints in this service are considered 'privilged' as in, the user calling the endpoint must be authorized and as such must included their serialized SignedJWT
inlcuded in the header of the request under the Authorization
header. In the test cases you'll see that we are including these headers with JWT's for your convenience when testing.
In Spring there is a way to automatically take this header and turn it into a SignedJWT
(This is already done for you by a provided filter here: JWTAuthenticationFilter). There is also a way to "ask" spring for this SignedJWT
by using the @AuthenticationPrincipal SignedJWT user
function parameter in the endpoint like so:
@GetMapping("/path")
public ResponseEntity<ResponseModel> endpoint(@AuthenticationPrincipal SignedJWT user)
{
...
}
- Our database schema has a
movie_person
table that has the list ofperson
in amovie
NOTE that this list does NOT contain the director, the director is only associated with a movie by thedirector_id
column. Every movie is guaranteed to have a director BUT not every movie hasperson
associated with them. - For the endpoint GET: Movie Search By Person Id do not account for director values, search only for
persons
inmovie_person
. This should prevent the SQL Queries from becoming too complex.
For queries marked as (Search by substring) make sure to have the value surrounded by '%' to allow for search by sub-string. Refer to this section in the activity: Wildcard String Matching
Returns a list of movies with basic information that match the given search parameters.
Since there can be ties in the movie list when giving a ORDER BY
parameter we must specify a Secondary sorting parameter: This sorting parameter will always be movie.id ASC
regardless of the Primary parameter. For example if we wanted to do sort the movies by their titles we would have the SQL Clause ORDER BY movie.title, movie.id
, note that ASC is the default direction and thus is optional to add.
Hidden Movies
Each movie in the movies.movie
table has a hidden
field. This field signifies if the movie is to be hidden away from users that do not have the Admin
or Employee
Role. If a user without either of these roles calls this endpoint, then all hidden movies must not be included in the results.
For the following string search parameters (title
, director
, genre
), you should use the LIKE
operator with the %
wildcard on both sides of the value. For example, if a value of 'knight' was given as the title
search parameter, then the sql command should look like this: title LIKE '%knight%'
GET /movie/search
📨  Headers | ||
---|---|---|
Name | Type | Description |
Authorization | String |
User's bearer token |
Transaction-ID | String |
Request's transaction id from the gateway service |
📝  Query | ||
Name | Type | Description |
title | String |
The movie's title (Search by substring) |
year | Integer |
The movie's release year |
director | String |
The movie's director (Search by substring) |
genre | String |
The movie's genre (Search by substring) |
limit | Integer |
Number of movies to list at one time: 10 (default), 25 , 50 , or 100 |
page | Integer |
The page for pagination: 1 (default) or any positive number over 0 |
orderBy | String |
Sorting parameter: title (default) or rating or year |
direction | String |
Sorting direction: asc (default) or desc |
📤  Response | ||
Model | Example | |
result: Result
code: Integer
message: String
movies: Movie[]
id: Long
title: String
year: Integer
director: String
rating: Double
backdropPath: String
posterPath: String
hidden: Boolean |
{
"result": {
"code": 2020,
"message": "Movies with the given search parameters found"
},
"movies": [
{
"id": 4154796,
"title": "Avengers: Endgame",
"year": 2019,
"director": "Joe Russo",
"rating": 8.6,
"backdropPath": "/7RyHsO4yDXtBv1zUU3mTpHeQ0d5.jpg",
"posterPath": "/or06FN3Dka5tukK1e9sl16pB3iy.jpg",
"hidden": false
},
{
"id": 4154796,
"title": "The Dark Knight Rises",
"year": 2012,
"director": "Christopher Nolan",
"rating": 8.0,
"backdropPath": "/f6ljQGv7WnJuwBPty017oPWfqjx.jpg",
"posterPath": "/dEYnvnUfXrqvqeRSqvIEtmzhoA8.jpg",
"hidden": false
}
]
} |
|
📦  Results | ||
Status | Code | Message |
âś… 200: Ok |
2020 | Movies with the given search parameters found |
âś… 200: Ok |
2021 | No movies found with the given search parameters |
âť— 400: Bad Request |
2000 | Invalid 'orderBy' value given |
âť— 400: Bad Request |
2001 | Invalid 'direction' value given |
âť— 400: Bad Request |
2002 | Invalid 'limit' value given |
âť— 400: Bad Request |
2003 | Invalid 'offset' value given |
Returns a list of movies with basic information that contain the given personId
as a person in the movie.
Since there can be ties in the movie list when giving a ORDER BY
parameter we must specify a Secondary sorting parameter: This sorting parameter will always be movie.id ASC
regardless of the Primary parameter. For example if we wanted to do sort the movies by their titles we would have the SQL Clause ORDER BY movie.title, movie.id
, note that ASC is the default direction and thus is optional to add.
Hidden Movies
Each movie in the movies.movie
table has a hidden
field. This field signifies if the movie is to be hidden away from users that do not have the Admin
or Employee
Role. If a user without either of these roles calls this endpoint, then all hidden movies must not be included in the results.
Do not account for director values, search only for persons
in movie_person
. This should prevent the SQL Queries from becoming too complex.
GET /movie/search/person/{personId}
📨  Headers | ||
---|---|---|
Name | Type | Description |
Authorization | String |
User's bearer token |
Transaction-ID | String |
Request's transaction id from the gateway service |
đź”–Â Â Path | ||
Name | Type | Description |
personId | Long |
Person ID for movies to search |
📝  Query | ||
Name | Type | Description |
limit | Integer |
Number of movies to list at one time: 10 (default), 25 , 50 , or 100 |
page | Integer |
The page for pagination: 1 (default) or any positive number over 0 |
orderBy | String |
Sorting parameter: title (default) or rating or year |
direction | String |
Sorting direction: asc (default) or desc |
📤  Response | ||
Model | Example | |
result: Result
code: Integer
message: String
movies: Movie[]
id: Long
title: String
year: Integer
director: String
rating: Double
backdropPath: String
posterPath: String
hidden: Boolean |
{
"result": {
"code": 2030,
"message": "Movies found with the personId"
},
"movies": [
{
"id": 1300854,
"title": "Iron Man 3",
"year": 2013,
"director": "Shane Black",
"rating": 7.0,
"backdropPath": "/n9X2DKItL3V0yq1q1jrk8z5UAki.jpg",
"posterPath": "/7XiGqZE8meUv7L4720L0tIDd7gO.jpg",
"hidden": false
},
{
"id": 4154796,
"title": "Avengers: Endgame",
"year": 2019,
"director": "Joe Russo",
"rating": 8.6,
"backdropPath": "/7RyHsO4yDXtBv1zUU3mTpHeQ0d5.jpg",
"posterPath": "/or06FN3Dka5tukK1e9sl16pB3iy.jpg",
"hidden": false
}
]
} |
|
📦  Results | ||
Status | Code | Message |
âś… 200: Ok |
2030 | Movies found with the personId |
âś… 200: Ok |
2031 | No Movies found with the personId |
âť— 400: Bad Request |
2000 | Invalid 'orderBy' value given |
âť— 400: Bad Request |
2001 | Invalid 'direction' value given |
âť— 400: Bad Request |
2002 | Invalid 'limit' value given |
âť— 400: Bad Request |
2003 | Invalid 'offset' value given |
Returns a movie with detailed information for the given movieId
.
The returned genres
lists must be returned in Alphabetical order of its name.
The returned persons
lists must be returned in Descending Popularity primary order, then Ascending Person ID secondary order.
Hidden Movies
Each movie in the movies.movie
table has a hidden
field. This field signifies if the movie is to be hidden away from users that do not have the Admin
or Employee
Role. If a user without either of these roles calls this endpoint, then all hidden movies must not be included in the results.
GET /movie/{movieId}
📨  Headers | ||
---|---|---|
Header | Type | Description |
Authorization | String |
User's bearer token |
Transaction-ID | String |
Request's transaction id from the gateway service |
đź”–Â Â Path | ||
Parameter | Type | Description |
movieId | Long |
Movie id of the movie to get |
📤  Response | ||
Model | Example | |
result: Result
code: Integer
message: String
movies: MovieDetail
id: Long
title: String
year: String
director: String
rating: Double
numVotes: Long
budget: Long
revenue: Long
overview: String
backdropPath: String
posterPath: String
hidden: Boolean
genres: Genre[]
genreId: Integer
name: String
persons: Person[]
personId: Integer
name: String |
{
"result": {
"code": 2010,
"message": "Movie found with the specified ID"
},
"movie": {
"id": 4154796,
"title": "Avengers: Endgame",
"year": 2019,
"director": "Joe Russo",
"rating": 8.6,
"numVotes": 5269,
"budget": 356000000,
"revenue": 2485499739,
"overview": "After the devastating events of Avengers: Infinity War... ",
"backdropPath": "/7RyHsO4yDXtBv1zUU3mTpHeQ0d5.jpg",
"posterPath": "/or06FN3Dka5tukK1e9sl16pB3iy.jpg",
"hidden": false
},
"genres": [
{
"id": 28,
"name": "Action"
}
],
"persons": [
{
"id": 3223,
"name": "Robert Downey Jr."
}
]
} |
|
📦  Results | ||
Status | Code | Message |
âś… 200: Ok |
2010 | Movie found with the specified ID |
âś… 200: Ok |
2011 | No Movie found for the specified ID |
Returns a list of people with basic information that match the given search parameters.
Since there can be ties in the person list when giving a ORDER BY
parameter we must specify a Secondary sorting parameter: This sorting parameter will always be person.id ASC
regardless of the Primary parameter. For example if we wanted to do sort the persons by their names we would have the SQL Clause ORDER BY person.name, person.id
, note that ASC is the default direction and thus is optional to add.
For the following string search parameters (name
, movieTitle
), you should use the LIKE
operator with the %
wildcard on both sides of the value. For example, if a value of 'knight' was given as the movieTitle
search parameter, then the sql command should look like this: title LIKE '%knight%'
GET /person/search
📨  Headers | ||
---|---|---|
Header | Type | Description |
Authorization | String |
User's bearer token |
Transaction-ID | String |
Request's transaction id from the gateway service |
📝  Query | ||
Name | Type | Description |
name | String |
Name of the person to search (Search by substring) |
birthday | String |
Birthday of the person to search |
movieTitle | String |
Movies to search the person in (Search by substring) |
limit | Integer |
Number of movies to list at one time: 10 (default), 25 , 50 , or 100 |
page | Integer |
The page for pagination: 1 (default) or any positive number over 0 |
orderBy | String |
Sorting parameter: name (default) or popularity or birthday |
direction | String |
Sorting direction: asc (default) or desc |
📤  Response | ||
Model | Example | |
result: Result
code: Integer
message: String
persons: id
personId: Long
name: String
birthday: String (nullable)
biography: String (nullable)
birthplace: String (nullable)
popularity: Float (nullable)
profilePath: String (nullable) |
{
"result": {
"code": 2050,
"message": "Persons with the given search parameters found"
},
"persons": [
{
"id": 3223,
"name": "Robert Downey Jr.",
"birthday": "1965-04-04",
"biography": "Robert John Downey Jr. (born April 4, 1965)...",
"birthplace": "Manhattan, New York City, New York, USA",
"popularity": 18.837,
"profilePath": "/r7WLn4Kbnqb6oJ8TmSI0e4LkWTj.jpg"
},
{
"id": 3894,
"name": "Christian Bale",
"birthday": "1974-01-30",
"biography": "A Welsh-born English actor...",
"birthplace": "Haverfordwest, Pembrokeshire, Wales, UK",
"popularity": 5.0,
"profilePath": "/vecCvACI2QhSE5fOoANeWDjxGKM.jpg"
}
]
} |
|
📦  Results | ||
Status | Code | Message |
âś… 200: Ok |
2050 | Persons with the given search parameters found |
âś… 200: Ok |
2051 | No Persons found with the given search parameters |
âť— 400: Bad Request |
2000 | Invalid 'orderBy' value given |
âť— 400: Bad Request |
2001 | Invalid 'direction' value given |
âť— 400: Bad Request |
2002 | Invalid 'limit' value given |
âť— 400: Bad Request |
2003 | Invalid 'offset' value given |
Return detailed information for the Person matching the given personId
GET /person/{personId}
📨  Headers | ||
---|---|---|
Header | Type | Description |
Authorization | String |
User's bearer token |
Transaction-ID | String |
Request's transaction id from the gateway service |
đź”–Â Â Path | ||
Parameter | Type | Description |
personId | Long |
Person id of the person to get |
📤  Response | ||
Model | Example | |
result: Result
code: Integer
message: String
person: PersonDetail
id: Long
name: String
birthday: String (nullable)
biography: String (nullable)
birthplace: String (nullable)
popularity: Float (nullable)
profilePath: String (nullable) |
{
"result": {
"code": 2040,
"message": "Person found with the specified ID"
},
"person": {
"id": 3223,
"name": "Robert Downey Jr.",
"birthday": "1965-04-04",
"biography": "Robert John Downey Jr. (born April 4, 1965)...",
"birthplace": "Manhattan, New York City, New York, USA",
"popularity": 18.837,
"profilePath": "/r7WLn4Kbnqb6oJ8TmSI0e4LkWTj.jpg"
}
} |
|
📦  Results | ||
Status | Code | Message |
âś… 200: Ok |
2040 | Person found with the specified ID |
âś… 200: Ok |
2041 | No Person found for the specified ID |