-
Notifications
You must be signed in to change notification settings - Fork 256
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
Rick and Morty First Commit #43
base: main
Are you sure you want to change the base?
Changes from 2 commits
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 | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,12 +1,27 @@ | ||||||||||||||||||
package mate.academy.rickandmorty; | ||||||||||||||||||
|
||||||||||||||||||
import java.util.List; | ||||||||||||||||||
import mate.academy.rickandmorty.dto.CharacterResponseDto; | ||||||||||||||||||
import mate.academy.rickandmorty.service.CharacterService; | ||||||||||||||||||
import mate.academy.rickandmorty.service.RickAndMortyClient; | ||||||||||||||||||
import org.springframework.beans.factory.annotation.Autowired; | ||||||||||||||||||
import org.springframework.boot.SpringApplication; | ||||||||||||||||||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||||||||||||||||
|
||||||||||||||||||
@SpringBootApplication | ||||||||||||||||||
public class Application { | ||||||||||||||||||
private static RickAndMortyClient rickAndMortyClient; | ||||||||||||||||||
private static CharacterService characterService; | ||||||||||||||||||
|
||||||||||||||||||
@Autowired | ||||||||||||||||||
public Application(CharacterService service, RickAndMortyClient client) { | ||||||||||||||||||
Application.rickAndMortyClient = client; | ||||||||||||||||||
Application.characterService = service; | ||||||||||||||||||
} | ||||||||||||||||||
Comment on lines
+15
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Application is responsible for booting your app. Consider using CommanLineRunner or ApplicationRunner.
Suggested change
|
||||||||||||||||||
|
||||||||||||||||||
public static void main(String[] args) { | ||||||||||||||||||
SpringApplication.run(Application.class, args); | ||||||||||||||||||
List<CharacterResponseDto> characters = rickAndMortyClient.getCharacters(); | ||||||||||||||||||
characterService.saveAll(characters); | ||||||||||||||||||
} | ||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,32 @@ | ||||||
package mate.academy.rickandmorty.controller; | ||||||
|
||||||
import io.swagger.v3.oas.annotations.Operation; | ||||||
import io.swagger.v3.oas.annotations.tags.Tag; | ||||||
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.RequestParam; | ||||||
import org.springframework.web.bind.annotation.RestController; | ||||||
|
||||||
@Tag(name = "Character management", description = "Endpoints for getting characters from DB") | ||||||
@RequiredArgsConstructor | ||||||
@RestController | ||||||
public class CharacterController { | ||||||
private final CharacterService characterService; | ||||||
|
||||||
@Operation(summary = "Get random character", | ||||||
description = "Get a random characters from Rick and Morty world") | ||||||
@GetMapping("/random") | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. REST URI convention violates here.
Suggested change
|
||||||
public CharacterDto getRandomCharacter() { | ||||||
return characterService.getRandomCharacter(); | ||||||
} | ||||||
|
||||||
@Operation(summary = "Search characters", | ||||||
description = "Search characters by name") | ||||||
@GetMapping("/search") | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Recall the REST URI convention.
Suggested change
|
||||||
public List<CharacterDto> searchCharacter(@RequestParam String name) { | ||||||
return characterService.findByName(name); | ||||||
} | ||||||
} |
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 String externalId; | ||
private String name; | ||
private String status; | ||
private String gender; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package mate.academy.rickandmorty.dto; | ||
|
||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | ||
import lombok.Data; | ||
|
||
@JsonIgnoreProperties(ignoreUnknown = true) | ||
@Data | ||
public class CharacterResponseDto { | ||
private Long id; | ||
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.dto; | ||
|
||
import java.util.List; | ||
import lombok.Data; | ||
|
||
@Data | ||
public class ListCharacterDto { | ||
private List<CharacterResponseDto> results; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package mate.academy.rickandmorty.mapper; | ||
|
||
import mate.academy.rickandmorty.dto.CharacterDto; | ||
import mate.academy.rickandmorty.dto.CharacterResponseDto; | ||
import mate.academy.rickandmorty.model.Character; | ||
import org.mapstruct.Mapper; | ||
import org.mapstruct.Mapping; | ||
|
||
@Mapper(componentModel = "spring") | ||
public interface CharacterMapper { | ||
@Mapping(source = "id", target = "externalId") | ||
@Mapping(target = "id", ignore = true) | ||
Character toModel(CharacterResponseDto responseDto); | ||
|
||
CharacterDto toDto(Character character); | ||
} |
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; | ||
|
||
@Data | ||
@Entity | ||
@Table(name = "characters") | ||
public class Character { | ||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
private String externalId; | ||
private String name; | ||
private String status; | ||
private String gender; | ||
} |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,11 @@ | ||||
package mate.academy.rickandmorty.repository; | ||||
|
||||
import java.util.List; | ||||
import mate.academy.rickandmorty.model.Character; | ||||
import org.springframework.data.jpa.repository.JpaRepository; | ||||
import org.springframework.stereotype.Repository; | ||||
|
||||
@Repository | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @repository is redundant here.
Suggested change
|
||||
public interface CharacterRepository extends JpaRepository<Character, Long> { | ||||
List<Character> findByNameContaining(String name); | ||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package mate.academy.rickandmorty.service; | ||
|
||
import java.util.List; | ||
import mate.academy.rickandmorty.dto.CharacterDto; | ||
import mate.academy.rickandmorty.dto.CharacterResponseDto; | ||
|
||
public interface CharacterService { | ||
CharacterDto getRandomCharacter(); | ||
|
||
void saveAll(List<CharacterResponseDto> listDto); | ||
|
||
List<CharacterDto> findByName(String name); | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,37 @@ | ||||||
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.List; | ||||||
import lombok.RequiredArgsConstructor; | ||||||
import mate.academy.rickandmorty.dto.CharacterResponseDto; | ||||||
import mate.academy.rickandmorty.dto.ListCharacterDto; | ||||||
import org.springframework.stereotype.Component; | ||||||
|
||||||
@Component | ||||||
@RequiredArgsConstructor | ||||||
public class RickAndMortyClient { | ||||||
private static final String CHARACTER_URL = "https://rickandmortyapi.com/api/character"; | ||||||
private final ObjectMapper objectMapper; | ||||||
|
||||||
public List<CharacterResponseDto> getCharacters() { | ||||||
HttpClient httpClient = HttpClient.newHttpClient(); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make HttpClient the spring bean.
Suggested change
|
||||||
HttpRequest request = HttpRequest.newBuilder() | ||||||
.GET() | ||||||
.uri(URI.create(CHARACTER_URL)) | ||||||
.build(); | ||||||
try { | ||||||
HttpResponse<String> response = httpClient | ||||||
.send(request, HttpResponse.BodyHandlers.ofString()); | ||||||
ListCharacterDto listCharacterDto = objectMapper | ||||||
.readValue(response.body(), ListCharacterDto.class); | ||||||
return listCharacterDto.getResults(); | ||||||
} catch (IOException | InterruptedException e) { | ||||||
throw new RuntimeException(e); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add method description here.
Suggested change
|
||||||
} | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,45 @@ | ||||||
package mate.academy.rickandmorty.service.impl; | ||||||
|
||||||
import java.util.List; | ||||||
import java.util.Random; | ||||||
import lombok.RequiredArgsConstructor; | ||||||
import mate.academy.rickandmorty.dto.CharacterDto; | ||||||
import mate.academy.rickandmorty.dto.CharacterResponseDto; | ||||||
import mate.academy.rickandmorty.mapper.CharacterMapper; | ||||||
import mate.academy.rickandmorty.model.Character; | ||||||
import mate.academy.rickandmorty.repository.CharacterRepository; | ||||||
import mate.academy.rickandmorty.service.CharacterService; | ||||||
import org.springframework.stereotype.Service; | ||||||
|
||||||
@RequiredArgsConstructor | ||||||
@Service | ||||||
public class CharacterServiceImpl implements CharacterService { | ||||||
private int listSize; | ||||||
private final Random random = new Random(); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are using spring, so such instantiations is bad practice.
Suggested change
|
||||||
private final CharacterRepository characterRepository; | ||||||
private final CharacterMapper mapper; | ||||||
|
||||||
@Override | ||||||
public CharacterDto getRandomCharacter() { | ||||||
int id = random.nextInt(listSize) + 1; | ||||||
return mapper.toDto(characterRepository.findById((long) id).orElseThrow( | ||||||
() -> new RuntimeException("Characters not found by id: " + id)) | ||||||
); | ||||||
} | ||||||
|
||||||
@Override | ||||||
public void saveAll(List<CharacterResponseDto> listDto) { | ||||||
List<Character> characters = listDto.stream() | ||||||
.map(mapper::toModel) | ||||||
.toList(); | ||||||
listSize = characters.size(); | ||||||
characterRepository.saveAll(characters); | ||||||
} | ||||||
|
||||||
@Override | ||||||
public List<CharacterDto> findByName(String name) { | ||||||
return characterRepository.findByNameContaining(name).stream() | ||||||
.map(mapper::toDto) | ||||||
.toList(); | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1 +1,11 @@ | ||||||
spring.datasource.url=jdbc:mysql://localhost:3306/rick_and_morty?serverTimezone=UTC | ||||||
spring.datasource.username=root | ||||||
spring.datasource.password=Romaxa051979 | ||||||
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver | ||||||
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it required property? if not should be removed
Suggested change
|
||||||
|
||||||
#spring.jpa.hibernate.ddl-auto=validate | ||||||
spring.jpa.hibernate.ddl-auto=create-drop | ||||||
server.servlet.context-path=/api | ||||||
spring.jpa.show-sql=true | ||||||
spring.jpa.open-in-view=false |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,8 @@ | ||
package mate.academy.rickandmorty; | ||
|
||
import org.junit.jupiter.api.Test; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
|
||
@SpringBootTest | ||
class ApplicationTests { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. empty class should be removed. or write the tests. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not fixed |
||
|
||
@Test | ||
void contextLoads() { | ||
} | ||
|
||
} |
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.
let spring to manage version