From 5bacc12f589a6be79be32e152ed02e5b1f25308e Mon Sep 17 00:00:00 2001 From: Andrii Date: Thu, 19 Oct 2023 11:29:31 +0300 Subject: [PATCH 1/2] added project rick-and-morty --- file.json | 142 ++++++++++++++++++ pom.xml | 63 +++++++- .../academy/rickandmorty/Application.java | 17 ++- .../rickandmorty/config/MapperConfig.java | 13 ++ .../controller/CharacterController.java | 19 +++ .../dto/external/CharacterInfoDto.java | 11 ++ .../dto/internal/CharacterResponseDto.java | 14 ++ .../CustomGlobalExceptionHandler.java | 17 +++ .../rickandmorty/mapper/CharacterMapper.java | 16 ++ .../academy/rickandmorty/model/Character.java | 17 +++ .../repository/CharacterRepository.java | 10 ++ .../service/CharacterService.java | 11 ++ .../service/CharacterServiceImpl.java | 34 +++++ .../service/RickAndMortyClient.java | 47 ++++++ src/main/resources/application.properties | 8 + .../rickandmorty/ApplicationTests.java | 10 +- 16 files changed, 436 insertions(+), 13 deletions(-) create mode 100644 file.json create mode 100644 src/main/java/mate/academy/rickandmorty/config/MapperConfig.java create mode 100644 src/main/java/mate/academy/rickandmorty/controller/CharacterController.java create mode 100644 src/main/java/mate/academy/rickandmorty/dto/external/CharacterInfoDto.java create mode 100644 src/main/java/mate/academy/rickandmorty/dto/internal/CharacterResponseDto.java create mode 100644 src/main/java/mate/academy/rickandmorty/exception/CustomGlobalExceptionHandler.java create mode 100644 src/main/java/mate/academy/rickandmorty/mapper/CharacterMapper.java create mode 100644 src/main/java/mate/academy/rickandmorty/model/Character.java create mode 100644 src/main/java/mate/academy/rickandmorty/repository/CharacterRepository.java create mode 100644 src/main/java/mate/academy/rickandmorty/service/CharacterService.java create mode 100644 src/main/java/mate/academy/rickandmorty/service/CharacterServiceImpl.java create mode 100644 src/main/java/mate/academy/rickandmorty/service/RickAndMortyClient.java diff --git a/file.json b/file.json new file mode 100644 index 00000000..c97e3163 --- /dev/null +++ b/file.json @@ -0,0 +1,142 @@ +{ + "info": { + "count": 826, + "pages": 42, + "next": null, + "prev": "https://rickandmortyapi.com/api/character?page=41" + }, + "results": [ + { + "id": 821, + "name": "Gotron", + "status": "unknown", + "species": "Robot", + "type": "Ferret Robot", + "gender": "Genderless", + "origin": { + "name": "Earth (Replacement Dimension)", + "url": "https://rickandmortyapi.com/api/location/20" + }, + "location": { + "name": "Earth (Replacement Dimension)", + "url": "https://rickandmortyapi.com/api/location/20" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/821.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/48" + ], + "url": "https://rickandmortyapi.com/api/character/821", + "created": "2021-11-02T17:15:24.788Z" + }, + { + "id": 822, + "name": "Young Jerry", + "status": "unknown", + "species": "Human", + "type": "", + "gender": "Male", + "origin": { + "name": "Earth (Unknown dimension)", + "url": "https://rickandmortyapi.com/api/location/30" + }, + "location": { + "name": "Earth (Unknown dimension)", + "url": "https://rickandmortyapi.com/api/location/30" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/822.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/51" + ], + "url": "https://rickandmortyapi.com/api/character/822", + "created": "2021-11-02T17:18:31.934Z" + }, + { + "id": 823, + "name": "Young Beth", + "status": "unknown", + "species": "Human", + "type": "", + "gender": "Female", + "origin": { + "name": "Earth (Unknown dimension)", + "url": "https://rickandmortyapi.com/api/location/30" + }, + "location": { + "name": "Earth (Unknown dimension)", + "url": "https://rickandmortyapi.com/api/location/30" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/823.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/51" + ], + "url": "https://rickandmortyapi.com/api/character/823", + "created": "2021-11-02T17:19:00.951Z" + }, + { + "id": 824, + "name": "Young Beth", + "status": "unknown", + "species": "Human", + "type": "", + "gender": "Female", + "origin": { + "name": "Earth (Unknown dimension)", + "url": "https://rickandmortyapi.com/api/location/30" + }, + "location": { + "name": "Earth (Unknown dimension)", + "url": "https://rickandmortyapi.com/api/location/30" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/824.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/51" + ], + "url": "https://rickandmortyapi.com/api/character/824", + "created": "2021-11-02T17:19:47.957Z" + }, + { + "id": 825, + "name": "Young Jerry", + "status": "unknown", + "species": "Human", + "type": "", + "gender": "Male", + "origin": { + "name": "Earth (Unknown dimension)", + "url": "https://rickandmortyapi.com/api/location/30" + }, + "location": { + "name": "Earth (Unknown dimension)", + "url": "https://rickandmortyapi.com/api/location/30" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/825.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/51" + ], + "url": "https://rickandmortyapi.com/api/character/825", + "created": "2021-11-02T17:20:14.305Z" + }, + { + "id": 826, + "name": "Butter Robot", + "status": "Alive", + "species": "Robot", + "type": "Passing Butter Robot", + "gender": "Genderless", + "origin": { + "name": "Earth (Replacement Dimension)", + "url": "https://rickandmortyapi.com/api/location/20" + }, + "location": { + "name": "Earth (Replacement Dimension)", + "url": "https://rickandmortyapi.com/api/location/20" + }, + "image": "https://rickandmortyapi.com/api/character/avatar/826.jpeg", + "episode": [ + "https://rickandmortyapi.com/api/episode/9" + ], + "url": "https://rickandmortyapi.com/api/character/826", + "created": "2021-11-02T17:24:37.458Z" + } + ] +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 0c754f19..07e44805 100644 --- a/pom.xml +++ b/pom.xml @@ -19,14 +19,19 @@ https://raw.githubusercontent.com/mate-academy/style-guides/master/java/checkstyle.xml + 0.2.0 + 1.5.5.Final org.springframework.boot spring-boot-starter - - + + org.springframework.boot + spring-boot-starter-web + + org.springframework.boot spring-boot-starter-test test @@ -41,7 +46,25 @@ com.h2database h2 - + + com.mysql + mysql-connector-j + + + org.projectlombok + lombok + + + org.mapstruct + mapstruct + ${mapstruct.version} + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.1.0 + + @@ -62,12 +85,38 @@ - ${maven.checkstyle.plugin.configLocation} - true - true - false + ${maven.checkstyle.plugin.configLocation} + true + true + false + src + + org.apache.maven.plugins + maven-compiler-plugin + + ${java.version} + ${java.version} + + + org.projectlombok + lombok + ${lombok.version} + + + org.projectlombok + lombok-mapstruct-binding + ${lombok.mapstruct.binding.version} + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + + + + diff --git a/src/main/java/mate/academy/rickandmorty/Application.java b/src/main/java/mate/academy/rickandmorty/Application.java index cdea84fc..844c22ae 100644 --- a/src/main/java/mate/academy/rickandmorty/Application.java +++ b/src/main/java/mate/academy/rickandmorty/Application.java @@ -1,12 +1,27 @@ package mate.academy.rickandmorty; +import lombok.RequiredArgsConstructor; +import mate.academy.rickandmorty.service.CharacterService; +import mate.academy.rickandmorty.service.RickAndMortyClient; +import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; @SpringBootApplication +@RequiredArgsConstructor public class Application { - + private final CharacterService characterService; + private final RickAndMortyClient rickAndMortyClient; + public static void main(String[] args) { SpringApplication.run(Application.class, args); } + + @Bean + public CommandLineRunner commandLineRunner() { + return args -> { + characterService.saveAll(rickAndMortyClient.getAllCharacters()); + }; + } } diff --git a/src/main/java/mate/academy/rickandmorty/config/MapperConfig.java b/src/main/java/mate/academy/rickandmorty/config/MapperConfig.java new file mode 100644 index 00000000..450e58db --- /dev/null +++ b/src/main/java/mate/academy/rickandmorty/config/MapperConfig.java @@ -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, + implementationPackage = ".impl" +) +public class MapperConfig { +} diff --git a/src/main/java/mate/academy/rickandmorty/controller/CharacterController.java b/src/main/java/mate/academy/rickandmorty/controller/CharacterController.java new file mode 100644 index 00000000..e80b5be2 --- /dev/null +++ b/src/main/java/mate/academy/rickandmorty/controller/CharacterController.java @@ -0,0 +1,19 @@ +package mate.academy.rickandmorty.controller; + +import lombok.RequiredArgsConstructor; +import mate.academy.rickandmorty.dto.internal.CharacterResponseDto; +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.RestController; + +@RestController +@RequiredArgsConstructor +public class CharacterController { + private final CharacterService characterService; + + @GetMapping("/characters/{id}") + public CharacterResponseDto getCharacter(@PathVariable Long id) { + return characterService.getCharacter(id); + } +} diff --git a/src/main/java/mate/academy/rickandmorty/dto/external/CharacterInfoDto.java b/src/main/java/mate/academy/rickandmorty/dto/external/CharacterInfoDto.java new file mode 100644 index 00000000..69e2b7b2 --- /dev/null +++ b/src/main/java/mate/academy/rickandmorty/dto/external/CharacterInfoDto.java @@ -0,0 +1,11 @@ +package mate.academy.rickandmorty.dto.external; + +import lombok.Data; + +@Data +public class CharacterInfoDto { + private Long id; + private String name; + private String status; + private String gender; +} diff --git a/src/main/java/mate/academy/rickandmorty/dto/internal/CharacterResponseDto.java b/src/main/java/mate/academy/rickandmorty/dto/internal/CharacterResponseDto.java new file mode 100644 index 00000000..73e1e353 --- /dev/null +++ b/src/main/java/mate/academy/rickandmorty/dto/internal/CharacterResponseDto.java @@ -0,0 +1,14 @@ +package mate.academy.rickandmorty.dto.internal; + +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +public class CharacterResponseDto { + private Long id; + private Long externalId; + private String name; + private String status; + private String gender; +} diff --git a/src/main/java/mate/academy/rickandmorty/exception/CustomGlobalExceptionHandler.java b/src/main/java/mate/academy/rickandmorty/exception/CustomGlobalExceptionHandler.java new file mode 100644 index 00000000..c9ebe71c --- /dev/null +++ b/src/main/java/mate/academy/rickandmorty/exception/CustomGlobalExceptionHandler.java @@ -0,0 +1,17 @@ +package mate.academy.rickandmorty.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +@ControllerAdvice +public class CustomGlobalExceptionHandler extends ResponseEntityExceptionHandler { + + @ExceptionHandler(RuntimeException.class) + public ResponseEntity handleAnyException(RuntimeException ex) { + String message = ex.getMessage(); + return new ResponseEntity<>(message, HttpStatus.BAD_REQUEST); + } +} diff --git a/src/main/java/mate/academy/rickandmorty/mapper/CharacterMapper.java b/src/main/java/mate/academy/rickandmorty/mapper/CharacterMapper.java new file mode 100644 index 00000000..680e62ea --- /dev/null +++ b/src/main/java/mate/academy/rickandmorty/mapper/CharacterMapper.java @@ -0,0 +1,16 @@ +package mate.academy.rickandmorty.mapper; + +import mate.academy.rickandmorty.config.MapperConfig; +import mate.academy.rickandmorty.dto.external.CharacterInfoDto; +import mate.academy.rickandmorty.dto.internal.CharacterResponseDto; +import mate.academy.rickandmorty.model.Character; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper(config = MapperConfig.class) +public interface CharacterMapper { + Character toModel(CharacterInfoDto dto); + + @Mapping(source = "id", target = "externalId") + CharacterResponseDto toDto(Character character); +} diff --git a/src/main/java/mate/academy/rickandmorty/model/Character.java b/src/main/java/mate/academy/rickandmorty/model/Character.java new file mode 100644 index 00000000..aed26f8e --- /dev/null +++ b/src/main/java/mate/academy/rickandmorty/model/Character.java @@ -0,0 +1,17 @@ +package mate.academy.rickandmorty.model; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.Data; + +@Entity +@Table(name = "characters") +@Data +public class Character { + @Id + private Long id; + private String name; + private String status; + private String gender; +} diff --git a/src/main/java/mate/academy/rickandmorty/repository/CharacterRepository.java b/src/main/java/mate/academy/rickandmorty/repository/CharacterRepository.java new file mode 100644 index 00000000..6dfbab36 --- /dev/null +++ b/src/main/java/mate/academy/rickandmorty/repository/CharacterRepository.java @@ -0,0 +1,10 @@ +package mate.academy.rickandmorty.repository; + +import mate.academy.rickandmorty.model.Character; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +public interface CharacterRepository extends JpaRepository { + @Query(value = "SELECT COUNT(*) FROM Character") + int getCountOfAllCharacters(); +} diff --git a/src/main/java/mate/academy/rickandmorty/service/CharacterService.java b/src/main/java/mate/academy/rickandmorty/service/CharacterService.java new file mode 100644 index 00000000..00eec6a1 --- /dev/null +++ b/src/main/java/mate/academy/rickandmorty/service/CharacterService.java @@ -0,0 +1,11 @@ +package mate.academy.rickandmorty.service; + +import java.util.List; +import mate.academy.rickandmorty.dto.external.CharacterInfoDto; +import mate.academy.rickandmorty.dto.internal.CharacterResponseDto; + +public interface CharacterService { + CharacterResponseDto getCharacter(Long id); + + void saveAll(List dtos); +} diff --git a/src/main/java/mate/academy/rickandmorty/service/CharacterServiceImpl.java b/src/main/java/mate/academy/rickandmorty/service/CharacterServiceImpl.java new file mode 100644 index 00000000..b6de887c --- /dev/null +++ b/src/main/java/mate/academy/rickandmorty/service/CharacterServiceImpl.java @@ -0,0 +1,34 @@ +package mate.academy.rickandmorty.service; + +import java.util.List; +import java.util.Random; +import lombok.RequiredArgsConstructor; +import mate.academy.rickandmorty.dto.external.CharacterInfoDto; +import mate.academy.rickandmorty.dto.internal.CharacterResponseDto; +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 { + private final CharacterRepository characterRepository; + private final CharacterMapper characterMapper; + + @Override + public CharacterResponseDto getCharacter(Long id) { + int countOfAllCharacters = characterRepository.getCountOfAllCharacters(); + if (id > countOfAllCharacters) { + throw new RuntimeException("A character with id " + id + " is not exist"); + } + Long randomId = new Random().nextLong(countOfAllCharacters); + return characterMapper.toDto(characterRepository.getReferenceById(randomId)).setId(id); + } + + @Override + public void saveAll(List dtos) { + List list = dtos.stream().map(characterMapper::toModel).toList(); + characterRepository.saveAll(list); + } +} diff --git a/src/main/java/mate/academy/rickandmorty/service/RickAndMortyClient.java b/src/main/java/mate/academy/rickandmorty/service/RickAndMortyClient.java new file mode 100644 index 00000000..9e329100 --- /dev/null +++ b/src/main/java/mate/academy/rickandmorty/service/RickAndMortyClient.java @@ -0,0 +1,47 @@ +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.Arrays; +import java.util.List; +import lombok.RequiredArgsConstructor; +import mate.academy.rickandmorty.dto.external.CharacterInfoDto; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class RickAndMortyClient { + private static final String URL = "https://rickandmortyapi.com/api/character?page=%s"; + private final ObjectMapper objectMapper; + + public List getAllCharacters() { + HttpClient httpClient = HttpClient.newHttpClient(); + + List dtosList = new ArrayList<>(); + for (int i = 0; true; i++) { + HttpRequest httpRequest = HttpRequest.newBuilder() + .GET() + .uri(URI.create(String.format(URL, i))) + .build(); + try { + HttpResponse response = + httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()); + String results = + objectMapper.readTree(response.body()).get("results").toString(); + CharacterInfoDto[] characterInfoDtos = + objectMapper.readValue(results, CharacterInfoDto[].class); + dtosList.addAll(Arrays.asList(characterInfoDtos)); + } catch (NullPointerException e) { + break; + } catch (IOException | InterruptedException e) { + throw new RuntimeException(e); + } + } + return dtosList; + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8b137891..1799655c 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,9 @@ +spring.datasource.url=jdbc:mysql://127.0.0.1:3306/rick-and-morty?serverTimezone=UTC +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +spring.datasource.username=root +spring.datasource.password=0054570334 + +spring.jpa.hibernate.ddl-auto=create-drop + +server.port=8082 diff --git a/src/test/java/mate/academy/rickandmorty/ApplicationTests.java b/src/test/java/mate/academy/rickandmorty/ApplicationTests.java index 8fec6af0..c96e9eda 100644 --- a/src/test/java/mate/academy/rickandmorty/ApplicationTests.java +++ b/src/test/java/mate/academy/rickandmorty/ApplicationTests.java @@ -5,9 +5,9 @@ @SpringBootTest class ApplicationTests { - - @Test - void contextLoads() { - } - + + @Test + void contextLoads() { + } + } From a8161e2f8f100897a022878558b13f7810b64cb4 Mon Sep 17 00:00:00 2001 From: Andrii Subash <126912806+andrii-subash@users.noreply.github.com> Date: Thu, 19 Oct 2023 19:16:28 +0300 Subject: [PATCH 2/2] Delete file.json I forgot to delete this file before commited --- file.json | 142 ------------------------------------------------------ 1 file changed, 142 deletions(-) delete mode 100644 file.json diff --git a/file.json b/file.json deleted file mode 100644 index c97e3163..00000000 --- a/file.json +++ /dev/null @@ -1,142 +0,0 @@ -{ - "info": { - "count": 826, - "pages": 42, - "next": null, - "prev": "https://rickandmortyapi.com/api/character?page=41" - }, - "results": [ - { - "id": 821, - "name": "Gotron", - "status": "unknown", - "species": "Robot", - "type": "Ferret Robot", - "gender": "Genderless", - "origin": { - "name": "Earth (Replacement Dimension)", - "url": "https://rickandmortyapi.com/api/location/20" - }, - "location": { - "name": "Earth (Replacement Dimension)", - "url": "https://rickandmortyapi.com/api/location/20" - }, - "image": "https://rickandmortyapi.com/api/character/avatar/821.jpeg", - "episode": [ - "https://rickandmortyapi.com/api/episode/48" - ], - "url": "https://rickandmortyapi.com/api/character/821", - "created": "2021-11-02T17:15:24.788Z" - }, - { - "id": 822, - "name": "Young Jerry", - "status": "unknown", - "species": "Human", - "type": "", - "gender": "Male", - "origin": { - "name": "Earth (Unknown dimension)", - "url": "https://rickandmortyapi.com/api/location/30" - }, - "location": { - "name": "Earth (Unknown dimension)", - "url": "https://rickandmortyapi.com/api/location/30" - }, - "image": "https://rickandmortyapi.com/api/character/avatar/822.jpeg", - "episode": [ - "https://rickandmortyapi.com/api/episode/51" - ], - "url": "https://rickandmortyapi.com/api/character/822", - "created": "2021-11-02T17:18:31.934Z" - }, - { - "id": 823, - "name": "Young Beth", - "status": "unknown", - "species": "Human", - "type": "", - "gender": "Female", - "origin": { - "name": "Earth (Unknown dimension)", - "url": "https://rickandmortyapi.com/api/location/30" - }, - "location": { - "name": "Earth (Unknown dimension)", - "url": "https://rickandmortyapi.com/api/location/30" - }, - "image": "https://rickandmortyapi.com/api/character/avatar/823.jpeg", - "episode": [ - "https://rickandmortyapi.com/api/episode/51" - ], - "url": "https://rickandmortyapi.com/api/character/823", - "created": "2021-11-02T17:19:00.951Z" - }, - { - "id": 824, - "name": "Young Beth", - "status": "unknown", - "species": "Human", - "type": "", - "gender": "Female", - "origin": { - "name": "Earth (Unknown dimension)", - "url": "https://rickandmortyapi.com/api/location/30" - }, - "location": { - "name": "Earth (Unknown dimension)", - "url": "https://rickandmortyapi.com/api/location/30" - }, - "image": "https://rickandmortyapi.com/api/character/avatar/824.jpeg", - "episode": [ - "https://rickandmortyapi.com/api/episode/51" - ], - "url": "https://rickandmortyapi.com/api/character/824", - "created": "2021-11-02T17:19:47.957Z" - }, - { - "id": 825, - "name": "Young Jerry", - "status": "unknown", - "species": "Human", - "type": "", - "gender": "Male", - "origin": { - "name": "Earth (Unknown dimension)", - "url": "https://rickandmortyapi.com/api/location/30" - }, - "location": { - "name": "Earth (Unknown dimension)", - "url": "https://rickandmortyapi.com/api/location/30" - }, - "image": "https://rickandmortyapi.com/api/character/avatar/825.jpeg", - "episode": [ - "https://rickandmortyapi.com/api/episode/51" - ], - "url": "https://rickandmortyapi.com/api/character/825", - "created": "2021-11-02T17:20:14.305Z" - }, - { - "id": 826, - "name": "Butter Robot", - "status": "Alive", - "species": "Robot", - "type": "Passing Butter Robot", - "gender": "Genderless", - "origin": { - "name": "Earth (Replacement Dimension)", - "url": "https://rickandmortyapi.com/api/location/20" - }, - "location": { - "name": "Earth (Replacement Dimension)", - "url": "https://rickandmortyapi.com/api/location/20" - }, - "image": "https://rickandmortyapi.com/api/character/avatar/826.jpeg", - "episode": [ - "https://rickandmortyapi.com/api/episode/9" - ], - "url": "https://rickandmortyapi.com/api/character/826", - "created": "2021-11-02T17:24:37.458Z" - } - ] -} \ No newline at end of file