-
Notifications
You must be signed in to change notification settings - Fork 308
add new file #263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
add new file #263
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package mate.academy.rickandmorty.config; | ||
|
||
import org.mapstruct.InjectionStrategy; | ||
import org.mapstruct.NullValueCheckStrategy; | ||
|
||
@org.mapstruct.MapperConfig( | ||
componentModel = "spring", | ||
injectionStrategy = InjectionStrategy.CONSTRUCTOR, | ||
nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS | ||
|
||
) | ||
public class MapperConfig { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package mate.academy.rickandmorty.controler; | ||
|
||
import io.swagger.v3.oas.annotations.Operation; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import mate.academy.rickandmorty.dto.CharacterDto; | ||
import mate.academy.rickandmorty.service.CharacterService; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RestController | ||
@RequestMapping("/characters") | ||
@RequiredArgsConstructor | ||
public class CharacterController { | ||
|
||
private final CharacterService characterService; | ||
|
||
@Operation(summary = "Get random character") | ||
@GetMapping("/random") | ||
public CharacterDto getRandomCharacter() { | ||
return characterService.getRandomCharacter(); | ||
} | ||
|
||
@Operation(summary = "Find character by name") | ||
@GetMapping() | ||
public List<CharacterDto> findCharacterByName(@RequestParam String name) { | ||
return characterService.findCharactersByName(name); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package mate.academy.rickandmorty.dto; | ||
|
||
import java.util.List; | ||
import lombok.Data; | ||
|
||
@Data | ||
public class CharacterDataDto { | ||
private List<CharacterDto> results; | ||
private CharacterInfoDto info; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package mate.academy.rickandmorty.dto; | ||
|
||
import lombok.Data; | ||
|
||
@Data | ||
public class CharacterDto { | ||
private Long id; | ||
private Long externalId; | ||
private String name; | ||
private String status; | ||
private String gender; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package mate.academy.rickandmorty.dto; | ||
|
||
import lombok.Data; | ||
|
||
@Data | ||
public class CharacterInfoDto { | ||
private String next; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package mate.academy.rickandmorty.mapper; | ||
|
||
import mate.academy.rickandmorty.config.MapperConfig; | ||
import mate.academy.rickandmorty.dto.CharacterDto; | ||
import mate.academy.rickandmorty.model.RickAndMortyCharacter; | ||
import org.mapstruct.Mapper; | ||
|
||
@Mapper(config = MapperConfig.class) | ||
public interface CharacterMapper { | ||
|
||
RickAndMortyCharacter toModel(CharacterDto characterDto); | ||
|
||
CharacterDto toDto(RickAndMortyCharacter rickAndMortyCharacter); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package mate.academy.rickandmorty.model; | ||
|
||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.Table; | ||
import lombok.Data; | ||
|
||
@Entity | ||
@Table(name = "characters") | ||
@Data | ||
public class RickAndMortyCharacter { | ||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
private Long externalId; | ||
|
||
private String name; | ||
private String status; | ||
private String gender; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package mate.academy.rickandmorty.repository; | ||
|
||
import java.util.List; | ||
import mate.academy.rickandmorty.model.RickAndMortyCharacter; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface CharacterRepository extends JpaRepository<RickAndMortyCharacter, Long> { | ||
List<RickAndMortyCharacter> findByNameContainingIgnoreCase(String name); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package mate.academy.rickandmorty.service; | ||
|
||
import java.util.List; | ||
import mate.academy.rickandmorty.dto.CharacterDto; | ||
|
||
public interface CharacterService { | ||
void saveAllCharacters(); | ||
|
||
CharacterDto getRandomCharacter(); | ||
|
||
List<CharacterDto> findCharactersByName(String name); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package mate.academy.rickandmorty.service; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import java.io.IOException; | ||
import java.net.URI; | ||
import java.net.http.HttpClient; | ||
import java.net.http.HttpRequest; | ||
import java.net.http.HttpResponse; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import mate.academy.rickandmorty.dto.CharacterDataDto; | ||
import mate.academy.rickandmorty.dto.CharacterDto; | ||
import org.springframework.stereotype.Component; | ||
|
||
@RequiredArgsConstructor | ||
@Component | ||
public class RickAndMortyClient { | ||
public static final String BASE_URL = "https://rickandmortyapi.com/api/character"; | ||
private final ObjectMapper objectMapper; | ||
|
||
public List<CharacterDto> getCharacters() { | ||
List<CharacterDto> allCharacters = new ArrayList<>(); | ||
HttpClient httpClient = HttpClient.newHttpClient(); | ||
String url = BASE_URL; | ||
try { | ||
while (url != null) { | ||
HttpRequest httpRequest = HttpRequest.newBuilder().GET() | ||
.uri(URI.create(url)).build(); | ||
HttpResponse<String> response = httpClient.send(httpRequest, | ||
HttpResponse.BodyHandlers.ofString()); | ||
CharacterDataDto characterResponse = objectMapper | ||
.readValue(response.body(), CharacterDataDto.class); | ||
allCharacters.addAll(characterResponse.getResults()); | ||
url = characterResponse.getInfo().getNext(); | ||
} | ||
return allCharacters; | ||
|
||
} catch (IOException | InterruptedException e) { | ||
throw new RuntimeException("Couldn't get characters from API", e); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package mate.academy.rickandmorty.service.impl; | ||
|
||
import jakarta.annotation.PostConstruct; | ||
import java.util.List; | ||
import java.util.Random; | ||
import lombok.RequiredArgsConstructor; | ||
import mate.academy.rickandmorty.dto.CharacterDto; | ||
import mate.academy.rickandmorty.mapper.CharacterMapper; | ||
import mate.academy.rickandmorty.model.RickAndMortyCharacter; | ||
import mate.academy.rickandmorty.repository.CharacterRepository; | ||
import mate.academy.rickandmorty.service.CharacterService; | ||
import mate.academy.rickandmorty.service.RickAndMortyClient; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class CharacterServiceImpl implements CharacterService { | ||
|
||
private final RickAndMortyClient characterClient; | ||
private final CharacterMapper characterMapper; | ||
private final CharacterRepository characterRepository; | ||
private final Random random = new Random(); | ||
|
||
@PostConstruct | ||
public void saveAllCharacters() { | ||
List<CharacterDto> characterDtos = characterClient.getCharacters(); | ||
List<RickAndMortyCharacter> rickAndMortyCharacters = characterDtos.stream() | ||
.map(characterMapper::toModel).toList(); | ||
characterRepository.saveAll(rickAndMortyCharacters); | ||
|
||
} | ||
|
||
@Override | ||
public CharacterDto getRandomCharacter() { | ||
List<RickAndMortyCharacter> rickAndMortyCharacters = characterRepository.findAll(); | ||
if (rickAndMortyCharacters.isEmpty()) { | ||
throw new RuntimeException("No characters found in database"); | ||
} | ||
int index = random.nextInt(rickAndMortyCharacters.size()); | ||
RickAndMortyCharacter rickAndMortyCharacter = rickAndMortyCharacters.get(index); | ||
return characterMapper.toDto(rickAndMortyCharacter); | ||
} | ||
|
||
@Override | ||
public List<CharacterDto> findCharactersByName(String name) { | ||
List<RickAndMortyCharacter> charactersByName = characterRepository | ||
.findByNameContainingIgnoreCase(name); | ||
return charactersByName.stream() | ||
.map(characterMapper::toDto).toList(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,9 @@ | ||
|
||
spring.datasource.url=jdbc:mysql://localhost:3306/testdb | ||
spring.datasource.username=root | ||
spring.datasource.password=Bs5QG4Rd2W_ | ||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver | ||
spring.jpa.hibernate.ddl-auto=create-drop | ||
spring.jpa.show-sql=true | ||
spring.jpa.open-in-view=false | ||
server.error.include-message=always | ||
server.error.include-binding-errors=always |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
externalId
field is of typeLong
, but the requirements specify that it should be a string in the API response. Ensure that this field is serialized as a string in the API response, either by changing its type toString
or by configuring serialization appropriately.