refactor(clients): update clients DTOs

This commit is contained in:
Rodrigo Verdiani 2025-10-22 16:36:04 -03:00
parent c25cd4435d
commit a31584ad35
12 changed files with 55 additions and 71 deletions

View File

@ -1,7 +1,7 @@
package com.magamochi.mangamochi.client; package com.magamochi.mangamochi.client;
import com.magamochi.mangamochi.model.dto.JikanMangaResponseDTO; import java.time.OffsetDateTime;
import com.magamochi.mangamochi.model.dto.JikanMangaSearchResponseDTO; import java.util.List;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
@ -10,8 +10,38 @@ import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "jikan", url = "https://api.jikan.moe/v4/manga") @FeignClient(name = "jikan", url = "https://api.jikan.moe/v4/manga")
public interface JikanClient { public interface JikanClient {
@GetMapping @GetMapping
JikanMangaSearchResponseDTO mangaSearch(@RequestParam String q); SearchResponse mangaSearch(@RequestParam String q);
@GetMapping("/{id}") @GetMapping("/{id}")
JikanMangaResponseDTO getMangaById(@PathVariable Long id); MangaResponse getMangaById(@PathVariable Long id);
record SearchResponse(List<MangaData> data) {
public record MangaData(Long mal_id, String title, List<TitleData> titles) {
public record TitleData(String type, String title) {}
}
}
record MangaResponse(MangaData data) {
public record MangaData(
Long mal_id,
ImageData images,
List<String> title_synonyms,
String status,
boolean publishing,
String synopsis,
Double score,
PublishData published,
List<AuthorData> authors,
List<GenreData> genres) {
public record ImageData(ImageUrls jpg) {
public record ImageUrls(String large_image_url) {}
}
public record PublishData(OffsetDateTime from, OffsetDateTime to) {}
public record AuthorData(Long mal_id, String name) {}
public record GenreData(Long mal_id, String name) {}
}
}
} }

View File

@ -1,7 +1,6 @@
package com.magamochi.mangamochi.client; package com.magamochi.mangamochi.client;
import com.magamochi.mangamochi.model.dto.RapidFuzzRequestDTO; import java.util.List;
import com.magamochi.mangamochi.model.dto.RapidFuzzResponseDTO;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
@ -9,5 +8,9 @@ import org.springframework.web.bind.annotation.RequestBody;
@FeignClient(name = "rapidFuzz", url = "http://127.0.0.1:9000/match-title") @FeignClient(name = "rapidFuzz", url = "http://127.0.0.1:9000/match-title")
public interface RapidFuzzClient { public interface RapidFuzzClient {
@PostMapping @PostMapping
RapidFuzzResponseDTO mangaSearch(@RequestBody RapidFuzzRequestDTO dto); Response mangaSearch(@RequestBody Request dto);
record Request(String title, List<String> options) {}
record Response(boolean match_found, String best_match, double similarity) {}
} }

View File

@ -1,7 +1,5 @@
package com.magamochi.mangamochi.client; package com.magamochi.mangamochi.client;
import com.magamochi.mangamochi.model.dto.WebScrapperClientRequestDTO;
import com.magamochi.mangamochi.model.dto.WebScrapperClientResponseDTO;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -12,5 +10,9 @@ public interface WebScrapperClient {
@PostMapping( @PostMapping(
consumes = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE) produces = MediaType.APPLICATION_JSON_VALUE)
WebScrapperClientResponseDTO scrape(@RequestBody WebScrapperClientRequestDTO dto); Response scrape(@RequestBody Request dto);
record Request(String url) {}
record Response(String page_source) {}
} }

View File

@ -12,6 +12,8 @@ import org.springframework.security.authentication.dao.DaoAuthenticationProvider
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
@ -55,18 +57,19 @@ public class SecurityConfig {
@Bean @Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors(cors -> cors.configurationSource(corsConfigurationSource())) http.cors(AbstractHttpConfigurer::disable)
.csrf(csrf -> csrf.disable()) .csrf(AbstractHttpConfigurer::disable)
.sessionManagement( .sessionManagement(
session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth.anyRequest().permitAll()) .authorizeHttpRequests(auth -> auth.anyRequest().permitAll())
.headers(headers -> headers.frameOptions(frame -> frame.disable())) .headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
.authenticationProvider(authenticationProvider()) .authenticationProvider(authenticationProvider())
.addFilterBefore(jwtRequestFilter(), UsernamePasswordAuthenticationFilter.class); .addFilterBefore(jwtRequestFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build(); return http.build();
} }
// TODO: maybe this can be removed
@Bean @Bean
public CorsConfigurationSource corsConfigurationSource() { public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration(); CorsConfiguration configuration = new CorsConfiguration();

View File

@ -1,28 +0,0 @@
package com.magamochi.mangamochi.model.dto;
import java.time.OffsetDateTime;
import java.util.List;
public record JikanMangaResponseDTO(MangaData data) {
public record MangaData(
Long mal_id,
ImageData images,
List<String> title_synonyms,
String status,
boolean publishing,
String synopsis,
Double score,
PublishData published,
List<AuthorData> authors,
List<GenreData> genres) {
public record ImageData(ImageUrls jpg) {
public record ImageUrls(String large_image_url) {}
}
public record PublishData(OffsetDateTime from, OffsetDateTime to) {}
public record AuthorData(Long mal_id, String name) {}
public record GenreData(Long mal_id, String name) {}
}
}

View File

@ -1,9 +0,0 @@
package com.magamochi.mangamochi.model.dto;
import java.util.List;
public record JikanMangaSearchResponseDTO(List<MangaData> data) {
public record MangaData(Long mal_id, String title, List<TitleData> titles) {
public record TitleData(String type, String title) {}
}
}

View File

@ -1,5 +0,0 @@
package com.magamochi.mangamochi.model.dto;
import java.util.List;
public record RapidFuzzRequestDTO(String title, List<String> options) {}

View File

@ -1,3 +0,0 @@
package com.magamochi.mangamochi.model.dto;
public record RapidFuzzResponseDTO(boolean match_found, String best_match, double similarity) {}

View File

@ -1,3 +0,0 @@
package com.magamochi.mangamochi.model.dto;
public record WebScrapperClientRequestDTO(String url) {}

View File

@ -1,3 +0,0 @@
package com.magamochi.mangamochi.model.dto;
public record WebScrapperClientResponseDTO(String page_source) {}

View File

@ -6,8 +6,6 @@ import com.google.common.util.concurrent.RateLimiter;
import com.magamochi.mangamochi.client.JikanClient; import com.magamochi.mangamochi.client.JikanClient;
import com.magamochi.mangamochi.client.RapidFuzzClient; import com.magamochi.mangamochi.client.RapidFuzzClient;
import com.magamochi.mangamochi.model.dto.ContentProviderMangaInfoResponseDTO; import com.magamochi.mangamochi.model.dto.ContentProviderMangaInfoResponseDTO;
import com.magamochi.mangamochi.model.dto.JikanMangaSearchResponseDTO;
import com.magamochi.mangamochi.model.dto.RapidFuzzRequestDTO;
import com.magamochi.mangamochi.model.entity.Manga; import com.magamochi.mangamochi.model.entity.Manga;
import com.magamochi.mangamochi.model.entity.MangaImportReview; import com.magamochi.mangamochi.model.entity.MangaImportReview;
import com.magamochi.mangamochi.model.entity.MangaProvider; import com.magamochi.mangamochi.model.entity.MangaProvider;
@ -95,13 +93,13 @@ public class MangaListService {
} }
var request = var request =
new RapidFuzzRequestDTO( new RapidFuzzClient.Request(
title, title,
jikanResults.stream() jikanResults.stream()
.flatMap( .flatMap(
results -> results ->
results.titles().stream() results.titles().stream()
.map(JikanMangaSearchResponseDTO.MangaData.TitleData::title)) .map(JikanClient.SearchResponse.MangaData.TitleData::title))
.toList()); .toList());
var fuzzResults = rapidFuzzClient.mangaSearch(request); var fuzzResults = rapidFuzzClient.mangaSearch(request);
@ -116,7 +114,7 @@ public class MangaListService {
.filter( .filter(
results -> results ->
results.titles().stream() results.titles().stream()
.map(JikanMangaSearchResponseDTO.MangaData.TitleData::title) .map(JikanClient.SearchResponse.MangaData.TitleData::title)
.toList() .toList()
.contains(fuzzResults.best_match())) .contains(fuzzResults.best_match()))
.findFirst(); .findFirst();

View File

@ -1,7 +1,6 @@
package com.magamochi.mangamochi.service; package com.magamochi.mangamochi.service;
import com.magamochi.mangamochi.client.WebScrapperClient; import com.magamochi.mangamochi.client.WebScrapperClient;
import com.magamochi.mangamochi.model.dto.WebScrapperClientRequestDTO;
import java.io.IOException; import java.io.IOException;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
@ -19,6 +18,6 @@ public class WebScrapperClientProxyService {
} }
private String scrape(String url) { private String scrape(String url) {
return webScrapperClient.scrape(new WebScrapperClientRequestDTO(url)).page_source(); return webScrapperClient.scrape(new WebScrapperClient.Request(url)).page_source();
} }
} }