Skip to content

Yana P - #1

Open
YanaP1312 wants to merge 5 commits into
HackYourAssignment:mainfrom
YanaP1312:main
Open

YanaP1312 wants to merge 5 commits into
HackYourAssignment:mainfrom
YanaP1312:main

Conversation

@YanaP1312

Copy link
Copy Markdown

Completed Week 6 assignment: database connection, web fetching, and interface testing.

  • Implemented user statistics endpoint with SQL‑computed fields and 404 handling
  • Implemented track lyrics endpoint using Spring RestClient with proper error responses
  • Added MockMvc integration tests:
    • 2 tests for user statistics (happy path + 404)
    • 3 tests for track lyrics (happy path + missing track + missing lyrics)
  • Configured PostgreSQL connection and loaded Postify schema/data
  • Organized package structure for controllers, services, client, dto, exceptions, repository and tests

@composix composix left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very solid implementation that feels production-ready. The coding patterns are consistent, and the code is kept simple and easy to read. I also like the minimal use of external libraries and the consistent use of Java records for DTOs.

Nice creative thinking as well: instead of trying to be a “database wizard”, the solution focuses on delivering a clear, maintainable, and reliable application.

}

@Bean
public RestClient lyricsRestClient(RestClient.Builder builder){

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely configured RestClient. Static request information, such as the base URL and default Accept header, is centralized in the configuration instead of being repeated across individual requests. This keeps the client code cleaner and easier to maintain.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice idea to wrap the external REST API calls in a dedicated service. This keeps the integration logic isolated and makes the code easier to maintain and test.

.retrieve()
.body(LyricApiResponse.class);
} catch(HttpClientErrorException.NotFound ex){
return null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning null here should be clearly documented, but using Optional would make the absence of a result more explicit and easier for callers to handle safely.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, thank you! Changed getLyrics() to return Optional instead of null — makes the absence of a result explicit in the signature and safer for callers to handle.


if (apiResponse == null || apiResponse.lyrics() == null || apiResponse.lyrics().isBlank()){
throw new LyricsNotFoundException(track.trackTitle(), track.artistName());
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If Optional were used in the LyricsClient, this code could be made more consistent with the findTrackWithArtist call. The caller could then use orElseThrow, making the “not found” flow more explicit and avoiding a separate null check.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — TrackLyricsService now uses .filter(...).orElseThrow(...) on the Optional returned by LyricsClient. Much cleaner than the manual null check, thanks for pointing this out!

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a useful startup check to verify that the application can connect to the database when it becomes ready. Consider using a logger instead of System.out.println, and make sure this class is registered as a Spring bean, for example with @Component.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed both — added @component so the class is actually picked up by Spring (turns out @eventlistener was silently never firing without it), and swapped System.out.println for a proper SLF4J logger. Good catch on the missing bean registration!

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the initiative to not force everything into one large SQL query, even though the exercise mentions that as an option for SQL wizards. Splitting the logic into smaller SQL queries and Java methods can make the solution easier to read, understand, and debug.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Splitting it into separate queries just felt more logical to me — easier to read, easier to debug later, and you don't need to hold the whole schema in your head to follow it. Though I'd love to get comfortable enough to fit it all into one query eventually!

@YanaP1312

Copy link
Copy Markdown
Author

@composix, thank you so much for such a thorough and thoughtful review — really appreciate the time you put into going through the whole PR in detail! Learned a lot from this round, especially about being explicit with Optional instead of relying on undocumented nulls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants