Skip to content

Commit 76f298e

Browse files
committed
The solution was done according to the requirements
1 parent c3bbe60 commit 76f298e

File tree

8 files changed

+312
-2
lines changed

8 files changed

+312
-2
lines changed

pom.xml

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<name>jv-rick-and-morty</name>
1515
<description>jv-rick-and-morty</description>
1616
<properties>
17-
<java.version>17</java.version>
17+
<java.version>21</java.version>
1818
<maven.checkstyle.plugin.version>3.1.1</maven.checkstyle.plugin.version>
1919
<maven.checkstyle.plugin.configLocation>
2020
https://raw.githubusercontent.com/mate-academy/style-guides/master/java/checkstyle.xml
@@ -41,6 +41,29 @@
4141
<groupId>com.h2database</groupId>
4242
<artifactId>h2</artifactId>
4343
</dependency>
44+
45+
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
46+
<dependency>
47+
<groupId>org.springframework.boot</groupId>
48+
<artifactId>spring-boot-starter-web</artifactId>
49+
<version>3.4.3</version>
50+
</dependency>
51+
52+
<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-starter-webmvc-ui -->
53+
<dependency>
54+
<groupId>org.springdoc</groupId>
55+
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
56+
<version>2.1.0</version>
57+
</dependency>
58+
59+
<!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j -->
60+
<dependency>
61+
<groupId>com.mysql</groupId>
62+
<artifactId>mysql-connector-j</artifactId>
63+
<version>9.2.0</version>
64+
</dependency>
65+
66+
4467
</dependencies>
4568

4669
<build>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package mate.academy.rickandmorty.config;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.web.client.RestTemplate;
6+
7+
@Configuration
8+
public class AppConfig {
9+
10+
@Bean
11+
public RestTemplate restTemplate() {
12+
return new RestTemplate();
13+
}
14+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package mate.academy.rickandmorty.controller;
2+
3+
import io.swagger.v3.oas.annotations.Operation;
4+
import io.swagger.v3.oas.annotations.tags.Tag;
5+
import java.util.List;
6+
import mate.academy.rickandmorty.model.Character;
7+
import mate.academy.rickandmorty.service.CharacterService;
8+
import org.springframework.beans.factory.annotation.Autowired;
9+
import org.springframework.web.bind.annotation.GetMapping;
10+
import org.springframework.web.bind.annotation.RequestMapping;
11+
import org.springframework.web.bind.annotation.RequestParam;
12+
import org.springframework.web.bind.annotation.RestController;
13+
14+
@RestController
15+
@RequestMapping("/api")
16+
@Tag(name = "Character API", description = "Endpoints for managing Rick & Morty characters")
17+
public class CharacterController {
18+
private final CharacterService characterService;
19+
20+
@Autowired
21+
public CharacterController(CharacterService characterService) {
22+
this.characterService = characterService;
23+
}
24+
25+
@Operation(summary = "Get a random character")
26+
@GetMapping("/character/random")
27+
public Character getRandomCharacter() {
28+
return characterService.getRandomCharacter();
29+
}
30+
31+
@Operation(summary = "Search characters by name")
32+
@GetMapping("/characters")
33+
public List<Character> searchCharacters(@RequestParam("name") String name) {
34+
return characterService.searchCharactersByName(name);
35+
}
36+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package mate.academy.rickandmorty.model;
2+
3+
import jakarta.persistence.Entity;
4+
import jakarta.persistence.GeneratedValue;
5+
import jakarta.persistence.GenerationType;
6+
import jakarta.persistence.Id;
7+
import jakarta.persistence.Table;
8+
9+
@Entity
10+
@Table(name = "characters")
11+
public class Character {
12+
@Id
13+
@GeneratedValue(strategy = GenerationType.IDENTITY)
14+
private Long id;
15+
private String externalId;
16+
private String name;
17+
private String status;
18+
private String gender;
19+
20+
public Long getId() {
21+
return id;
22+
}
23+
24+
public void setId(Long id) {
25+
this.id = id;
26+
}
27+
28+
public String getExternalId() {
29+
return externalId;
30+
}
31+
32+
public void setExternalId(String externalId) {
33+
this.externalId = externalId;
34+
}
35+
36+
public String getName() {
37+
return name;
38+
}
39+
40+
public void setName(String name) {
41+
this.name = name;
42+
}
43+
44+
public String getStatus() {
45+
return status;
46+
}
47+
48+
public void setStatus(String status) {
49+
this.status = status;
50+
}
51+
52+
public String getGender() {
53+
return gender;
54+
}
55+
56+
public void setGender(String gender) {
57+
this.gender = gender;
58+
}
59+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package mate.academy.rickandmorty.repository;
2+
3+
import java.util.List;
4+
import mate.academy.rickandmorty.model.Character;
5+
import org.springframework.data.jpa.repository.JpaRepository;
6+
import org.springframework.stereotype.Repository;
7+
8+
@Repository
9+
public interface CharacterRepository extends JpaRepository<Character, Long> {
10+
List<Character> findByNameContainingIgnoreCase(String name);
11+
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
package mate.academy.rickandmorty.service;
2+
3+
import jakarta.annotation.PostConstruct;
4+
import java.util.List;
5+
import mate.academy.rickandmorty.model.Character;
6+
import mate.academy.rickandmorty.repository.CharacterRepository;
7+
import org.springframework.stereotype.Service;
8+
import org.springframework.web.client.RestTemplate;
9+
10+
@Service
11+
public class CharacterService {
12+
private static final String EXTERNAL_API_URL = "https://rickandmortyapi.com/api/character";
13+
private final CharacterRepository characterRepository;
14+
private final RestTemplate restTemplate;
15+
16+
public CharacterService(CharacterRepository characterRepository, RestTemplate restTemplate) {
17+
this.characterRepository = characterRepository;
18+
this.restTemplate = restTemplate;
19+
}
20+
21+
@PostConstruct
22+
public void loadCharacters() {
23+
24+
String url = EXTERNAL_API_URL;
25+
do {
26+
ExternalApiResponse response = restTemplate.getForObject(url,
27+
ExternalApiResponse.class);
28+
if (response != null && response.getResults() != null) {
29+
for (ExternalCharacter ec : response.getResults()) {
30+
Character character = new Character();
31+
character.setExternalId(String.valueOf(ec.getId()));
32+
character.setName(ec.getName());
33+
character.setStatus(ec.getStatus());
34+
character.setGender(ec.getGender());
35+
characterRepository.save(character);
36+
}
37+
url = response.getInfo().getNext();
38+
} else {
39+
url = null;
40+
}
41+
} while (url != null);
42+
}
43+
44+
public List<Character> searchCharactersByName(String name) {
45+
return characterRepository.findByNameContainingIgnoreCase(name);
46+
}
47+
48+
public Character getRandomCharacter() {
49+
List<Character> characters = characterRepository.findAll();
50+
if (characters.isEmpty()) {
51+
return null;
52+
}
53+
int randomIndex = (int) (Math.random() * characters.size());
54+
return characters.get(randomIndex);
55+
}
56+
57+
public static class ExternalApiResponse {
58+
private Info info;
59+
private List<ExternalCharacter> results;
60+
61+
public Info getInfo() {
62+
return info;
63+
}
64+
65+
public void setInfo(Info info) {
66+
this.info = info;
67+
}
68+
69+
public List<ExternalCharacter> getResults() {
70+
return results;
71+
}
72+
73+
public void setResults(List<ExternalCharacter> results) {
74+
this.results = results;
75+
}
76+
}
77+
78+
public static class Info {
79+
private int count;
80+
private int pages;
81+
private String next;
82+
private String prev;
83+
84+
public int getCount() {
85+
return count;
86+
}
87+
88+
public void setCount(int count) {
89+
this.count = count;
90+
}
91+
92+
public int getPages() {
93+
return pages;
94+
}
95+
96+
public void setPages(int pages) {
97+
this.pages = pages;
98+
}
99+
100+
public String getNext() {
101+
return next;
102+
}
103+
104+
public void setNext(String next) {
105+
this.next = next;
106+
}
107+
108+
public String getPrev() {
109+
return prev;
110+
}
111+
112+
public void setPrev(String prev) {
113+
this.prev = prev;
114+
}
115+
}
116+
117+
public static class ExternalCharacter {
118+
private int id;
119+
private String name;
120+
private String status;
121+
private String gender;
122+
123+
public int getId() {
124+
return id;
125+
}
126+
127+
public void setId(int id) {
128+
this.id = id;
129+
}
130+
131+
public String getName() {
132+
return name;
133+
}
134+
135+
public void setName(String name) {
136+
this.name = name;
137+
}
138+
139+
public String getStatus() {
140+
return status;
141+
}
142+
143+
public void setStatus(String status) {
144+
this.status = status;
145+
}
146+
147+
public String getGender() {
148+
return gender;
149+
}
150+
151+
public void setGender(String gender) {
152+
this.gender = gender;
153+
}
154+
155+
}
156+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,12 @@
1+
spring.datasource.url=jdbc:mysql://localhost:3306/rickandmorty_db
2+
spring.datasource.username=root
3+
spring.datasource.password=12345678
4+
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
5+
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
16

7+
spring.jpa.hibernate.ddl-auto=update
8+
spring.jpa.show-sql=true
9+
10+
# Swagger/OpenAPI configuration (using springdoc-openapi)
11+
springdoc.api-docs.path=/api-docs
12+
springdoc.swagger-ui.path=/swagger-ui.html
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
spring.datasource.url=jdbc:h2:mem:testdb
22
spring.datasource.driverClassName=org.h2.Driver
33
spring.datasource.username=sa
4-
spring.datasource.password=password
4+
spring.datasource.password=
55
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

0 commit comments

Comments
 (0)