-
Notifications
You must be signed in to change notification settings - Fork 237
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
created API, Rick and Morty #181
base: main
Are you sure you want to change the base?
Changes from 3 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 |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package mate.academy.rickandmorty.config; | ||
|
||
import org.mapstruct.InjectionStrategy; | ||
import org.mapstruct.NullValueCheckStrategy; | ||
|
||
@org.mapstruct.MapperConfig( | ||
componentModel = "spring", | ||
injectionStrategy = InjectionStrategy.CONSTRUCTOR, | ||
nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, | ||
implementationName = "<CLASS_NAME>Impl" | ||
) | ||
public class MapperConfig { | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
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.PathVariable; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RequiredArgsConstructor | ||
@RestController | ||
@RequestMapping("/characters") | ||
@Tag(name = "Characters", description = "Operations related to characters") | ||
public class CharacterController { | ||
private final CharacterService characterService; | ||
|
||
@GetMapping("/random") | ||
@Operation(summary = "Get a random character", | ||
description = "Retrieve a random character from \"Rick and Morty\"") | ||
public CharacterDto getRandomCharacter() { | ||
return characterService.getRandomCharacter(); | ||
} | ||
|
||
@GetMapping("/search/{name}") | ||
@Operation(summary = "Get characters by name", | ||
description = "Retrieve a list of characters name fragment") | ||
public List<CharacterDto> getBookByName(@PathVariable String name) { | ||
return characterService.searchCharacters(name); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package mate.academy.rickandmorty.dto; | ||
|
||
public record CharacterDto(Long id, String externalId, String name, String status, String gender) { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package mate.academy.rickandmorty.dto; | ||
|
||
import jakarta.validation.constraints.NotBlank; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.Setter; | ||
|
||
@Setter | ||
@Getter | ||
@AllArgsConstructor | ||
public class CreateCharacterRequestDto { | ||
@NotBlank | ||
private String externalId; | ||
@NotBlank | ||
private String name; | ||
@NotBlank | ||
private String status; | ||
@NotBlank | ||
private String gender; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package mate.academy.rickandmorty.mapper; | ||
|
||
import mate.academy.rickandmorty.config.MapperConfig; | ||
import mate.academy.rickandmorty.dto.CharacterDto; | ||
import mate.academy.rickandmorty.model.Character; | ||
import org.mapstruct.Mapper; | ||
|
||
@Mapper(config = MapperConfig.class) | ||
public interface CharacterMapper { | ||
CharacterDto toDo(Character character); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
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.Getter; | ||
import lombok.Setter; | ||
|
||
@Entity | ||
@Getter | ||
@Setter | ||
@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,12 @@ | ||
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 | ||
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,10 @@ | ||
package mate.academy.rickandmorty.service; | ||
|
||
import java.util.List; | ||
import mate.academy.rickandmorty.dto.CharacterDto; | ||
|
||
public interface CharacterService { | ||
CharacterDto getRandomCharacter(); | ||
|
||
List<CharacterDto> searchCharacters(String name); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package mate.academy.rickandmorty.service; | ||
|
||
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.Character; | ||
import mate.academy.rickandmorty.repository.CharacterRepository; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class CharacterServiceImpl implements CharacterService { | ||
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. Didn't find service where you use |
||
private final CharacterRepository characterRepository; | ||
private final CharacterMapper characterMapper; | ||
|
||
@Override | ||
public CharacterDto getRandomCharacter() { | ||
List<Character> characters = characterRepository.findAll(); | ||
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. better extract random to a class level field, not to recreate it needlessly per each method invocation |
||
return characterMapper | ||
.toDo(characters.get(random.nextInt(characters.size()))); | ||
} | ||
|
||
@Override | ||
public List<CharacterDto> searchCharacters(String name) { | ||
return characterRepository.findByNameContaining(name).stream() | ||
.map(characterMapper::toDo) | ||
.toList(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package mate.academy.rickandmorty.service; | ||
|
||
import lombok.AllArgsConstructor; | ||
import mate.academy.rickandmorty.model.Character; | ||
import mate.academy.rickandmorty.repository.CharacterRepository; | ||
import org.json.JSONArray; | ||
import org.json.JSONObject; | ||
import org.springframework.boot.CommandLineRunner; | ||
import org.springframework.stereotype.Component; | ||
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; | ||
|
||
@Component | ||
@AllArgsConstructor | ||
public class DataInitializer implements CommandLineRunner { | ||
private static final String URL = "https://rickandmortyapi.com/api/character"; | ||
|
||
private CharacterRepository characterRepository; | ||
|
||
@Override | ||
public void run(String... args) throws IOException, InterruptedException { | ||
HttpClient httpClient = HttpClient.newHttpClient(); | ||
String nextPageUrl = URL; | ||
|
||
List<Character> characters = new ArrayList<>(); | ||
while (nextPageUrl != null) { | ||
HttpRequest httpRequest = HttpRequest.newBuilder() | ||
.GET() | ||
.uri(URI.create(nextPageUrl)) | ||
.build(); | ||
HttpResponse<String> response = httpClient | ||
.send(httpRequest, HttpResponse.BodyHandlers.ofString()); | ||
|
||
JSONObject jsonResponse = new JSONObject(response.body()); | ||
JSONArray resultsArray = jsonResponse.getJSONArray("results"); | ||
|
||
for (int i = 0; i < resultsArray.length(); i++) { | ||
JSONObject characterJson = resultsArray.getJSONObject(i); | ||
|
||
Character character = new Character(); | ||
character.setExternalId(String.valueOf(characterJson.getInt("id"))); | ||
character.setName(characterJson.getString("name")); | ||
character.setStatus(characterJson.getString("status")); | ||
character.setGender(characterJson.getString("gender")); | ||
|
||
characters.add(character); | ||
} | ||
|
||
nextPageUrl = | ||
jsonResponse.isNull("next") ? | ||
null : jsonResponse.getJSONObject("info").getString("next"); | ||
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. doesn't look nice tbh ,let's use objectMapper.readValue() to read JSON into DTOs |
||
} | ||
characterRepository.saveAll(characters); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,5 @@ | ||
spring.datasource.url=jdbc:mysql://localhost:3306/rick_and_morty | ||
spring.datasource.username=root | ||
spring.datasource.password=root12345 | ||
spring.jpa.hibernate.ddl-auto=update | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,9 +5,7 @@ | |
|
||
@SpringBootTest | ||
class ApplicationTests { | ||
|
||
@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.