commit cd132715c927c2bc3c4ebadd4f6d89670286eada Author: roland-dittel-joyn <68650544+roland-dittel-joyn@users.noreply.github.com> Date: Fri Dec 8 14:37:40 2023 +0100 Initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..642e43e --- /dev/null +++ b/README.md @@ -0,0 +1,96 @@ +# Movie Metadata Search + +## Preface + +Hello, + +this is part of your interview with Joyn that aims to test your ability to write services that efficiently solve problems we have in our business. + +Please read this document carefully before starting, as it outlines your task, the constraints and by what criteria you will be evaluated. + +Use git to document your work. When finished, please create a pull request on the `master` branch, according to the following naming convention: `-solution` + +We will look at the git history of your pull request to determine the way you approached this. **Please do not squash commits or bundle many unrelated changes into one large commit.** + +## The service + +You are tasked to implement a RESTful API that provides the following two basic functionalities to retrieve movie metadata from a content catalogue. + +The data used for this comes from two sources: +- Typically, our own movie data would come from a database, but to simplify this, we use the static json files in `./movies` as our content catalogue. +- OMDb movie metadata can be retrieved as follows: + - `https://www.omdbapi.com/?i=&apikey=&plot=full` + - You can use the following API key: `68fd98ab` (Limited to 1000 requests per day) + - Please see https://www.omdbapi.com for details + +#### Getting enriched movie metadata (title, description, ..) + +The first task is to merge movie metadata from our systems with movie metadata from the Open Movie Database (OMDb). + +- Calling `GET /api/movies/:id` should return a JSON object representing the merged movie object. +- `:id` is an alphanumeric value that can either refer to OMDb movie ids or our internal ids. +- When merging the two objects with the same fields (i.e. both JSON objects have a `title` / `Title`), it depends on the name of the field, which metadata should be used. +- The following rules apply, with capitalized field names (i.e. `Title` vs `title`) always referring to OMDb data + - `Title` overwrites `title` + - `Plot` overwrites `description` + - `duration` overwrites `Runtime` + - `userrating` will become part of `Ratings`, applying a similar logic than `Ratings` currently has + - `Director`, `Writer` and `Actors` should be transformed from `String` to an `String[]` +- Fields not covered by any of these rules should be merged into the resulting JSON in a normalized way +- If fields are unclear, make reasonable assumptions and choose your implementation accordingly + +#### Search movies in our catalogue + +We want to be able to search movies in our catalogue. To that end, we implement a simple search that returns a movie object if **all** search terms are true. A search term is a query param in your REST call in the form of `=` + +- If no search term is provided, return all movies +- Search terms are **case-insensitive** +- Search is performed on the merged json objects of movies +- If `` is of type `Number` or `String` in the movie metadata, the search matches if the values are equal, i.e. `?title=Sin City` matches `3532674.json` +- If `` is of type `Array` in the movie metadata, the search matches if the `` is contained in the array, i.e. `?director=Frank Miller` matches `3532674.json` / the corresponding OMBd object +- Calling `GET /api/movies?=` should return a JSON array representing all movies that match the search criteria + +## Additional Tasks + +The following tasks are optional but it would be nice to have at least one, in case you have additional time. + +### AWS Lambda Function + +Use the code you have written and create an [AWS Lambda function](https://aws.amazon.com/lambda/). +For setting up the Lambda function and the deployment please use [IaC](https://en.wikipedia.org/wiki/Infrastructure_as_code). +You are free to use any framework or tool for this task. + +### Caching + +To improve response times it might be beneficial to add caching to the service. Go through your implementation and check where adding caching would make sense. Then pick an appropriate caching mechanism and implement it in your code. Please also take [TTLs](https://en.wikipedia.org/wiki/Time_to_live) and application scaling into account. + +## Constraints + +- Use TypeScript +- Use node.js in version 14+ +- Do not introduce any system dependencies (databases, caches, search engines, docker, ..) to solve this task. This task is about your problem solving skills and not about creating a production ready system. It should not require more than `npm install` and `npm start` to have a running service. +- 72h after being added to the project, your pushing rights will be revoked and the latest commit of your implementation will be the basis for your evaluation. +- We respect your time and encourage you to keep it simple: You are not expected to spend days on this - just proof that you know how to write great software in node.js + +## Evaluation criteria + +In general you can think of the evaluation being a thorough peer review of your code. +You will be evaluated by a number of criteria, among others: + +- How well did you apply engineering best practices (general & node.js specific)? +- Is the service working as intended? +- How readable is your code? +- Does the service solve the problem + - correctly? + - efficiently? +- Is your code consistent in itself (styling, language constructs, ..)? +- Appropriate use of 3rd party modules +- We do **not** expect you to have a high test coverage, **BUT** it is important that you demonstrate that you know how to write testable code and provide a few tests that showcase this. +- Proper use of git +- Making good assumptions and documenting them + +## Questions + +If you have any further questions, please open an issue in this GitHub repository and we'll try to give you an answer as quickly as possible. + +### Good luck diff --git a/movies/11043689.json b/movies/11043689.json new file mode 100644 index 0000000..b403904 --- /dev/null +++ b/movies/11043689.json @@ -0,0 +1,25 @@ +{ + "description": "Der im Exil lebende Jedi-Ritter Obi-Wan Kenobi nimmt sich einen Mann namens Luke Skywalker als Schüler. Zusammen helfen sie der Rebellion, die Pläne des bösen Imperiums und des Sith-Lords Darth Vader zu vereiteln. ", + "duration": 120, + "id": 11043689, + "imdbId": "tt0076759", + "languages": [ + "de", + "en" + ], + "originalLanguage": "en", + "productionYear": 1977, + "studios": [ + "FOX", + "Paramount" + ], + "title": "Star Wars: Eine neue Hoffnung", + "userrating": { + "countStar1": 5, + "countStar2": 3, + "countStar3": 88, + "countStar4": 101, + "countStar5": 417, + "countTotal": 614 + } +} diff --git a/movies/11528860.json b/movies/11528860.json new file mode 100644 index 0000000..aaf717c --- /dev/null +++ b/movies/11528860.json @@ -0,0 +1,24 @@ +{ + "description": "Unter der Obhut des Panthers Baghira wächst das Findelkind Mogli bei einer Wolfsfamilie auf. Doch da erschüttert die Rückkehr des menschenfressenden Tigers Shir Khan den Dschungel. Die Sorge um Mogli zwingt Baghira zu der einzig möglichen Entscheidung.", + "duration": 75, + "id": 11528860, + "imdbId": "tt0061852", + "languages": [ + "de", + "en" + ], + "originalLanguage": "en", + "productionYear": 1967, + "studios": [ + "Disney" + ], + "title": "Das Dschungelbuch", + "userrating": { + "countStar1": 1, + "countStar2": 2, + "countStar3": 49, + "countStar4": 37, + "countStar5": 140, + "countTotal": 229 + } +} diff --git a/movies/3532674.json b/movies/3532674.json new file mode 100644 index 0000000..3d1551b --- /dev/null +++ b/movies/3532674.json @@ -0,0 +1,25 @@ +{ + "description": "Im Sündenpfuhl Sin City werden drei Geschichten parallel erzählt: Der Polizist Hartigan jagt einen Pädophilen, der Outlaw Dwight muss im Rotlichtbezirk untertauchen und dem Schläger Marv wird ein Mord angehängt. ", + "duration": 119, + "id": 3532674, + "imdbId": "tt0401792", + "languages": [ + "de", + "en" + ], + "originalLanguage": "en", + "productionYear": 2005, + "studios": [ + "Studiocanal", + "Paramount" + ], + "title": "Sin City", + "userrating": { + "countStar1": 169, + "countStar2": 152, + "countStar3": 751, + "countStar4": 847, + "countStar5": 1197, + "countTotal": 3116 + } +} diff --git a/movies/5979300.json b/movies/5979300.json new file mode 100644 index 0000000..bab9f52 --- /dev/null +++ b/movies/5979300.json @@ -0,0 +1,24 @@ +{ + "description": "1912: Der junge Indiana Jones will Grabräubern das Kreuz von Coronado abluchsen, um es in ein Museum zu bringen. Nach einem Zeitsprung ins Jahr 1938 kämpft Indy wieder um das Kreuz, diesmal erfolgreich. Anschließend soll er den Heiligen Gral suchen.", + "duration": 127, + "id": 5979300, + "imdbId": "tt0097576", + "languages": [ + "de", + "en" + ], + "originalLanguage": "en", + "productionYear": 1989, + "studios": [ + "Paramount" + ], + "title": "Indiana Jones und der letzte Kreuzzug", + "userrating": { + "countStar1": 20, + "countStar2": 24, + "countStar3": 1103, + "countStar4": 1224, + "countStar5": 2349, + "countTotal": 4720 + } +}