Boa tarde!
É possível consumir uma API externa feita em Graphql utilizando Spring?
Se sim poderia mostrar um exemplo?
Boa tarde!
É possível consumir uma API externa feita em Graphql utilizando Spring?
Se sim poderia mostrar um exemplo?
Tentei utlizar o RestTemplate mas é retornado null nos campos, como seria a implementação com webclient?
@Service
public class ConsumeGraphqlService {
@Autowired
private WebClient webClient;
String url = "https://rickandmortyapi.com/graphql";
// site usado para formatar a query em json https://jsonlint.com/
String query = "{\n" + " \"query\": \"query { episodesByIds(ids: [1, 2]) { name characters { name } }}\"\n"
+ "}";
public ResponseEntity<FilmeDto> consumirApi(){
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.add("Content-type", "application/json");
ResponseEntity<FilmeDto> response = restTemplate.postForEntity(url, new HttpEntity<>(query,headers),FilmeDto.class);
return response;
}
@RestController
@RequestMapping("/api/graphql")
public class ConsumeGraphqlController {
@Autowired
private ConsumeGraphqlService service;
@GetMapping("/chamarapi")
public ResponseEntity<FilmeDto> chamarApi() {
ResponseEntity<FilmeDto> filmes = service.consumirApi();
return filmes;
}
Oi Marcos,
Você tem a depéndencia webflux
do Spring Boot no seu projeto?
Desse jeito que você fez deveria funcionar. Talvez o problema seja no seu DTO, que pode não estar refletindo os dados no formato que são devolvidos pela API.
Posta aqui o código da sua classe DTO.
Oi Rodrigo, Segue o pom.xml e o DTO que fiz no projeto
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>br.com.consume.graphql</groupId>
<artifactId>consume-graphql</artifactId>
<version>1</version>
<name>consume-graphql</name>
<description>consume-graphql</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
CharactersDto
import lombok.Data;
@Data
public class CharactersDto {
private String name;
}
FilmeDto
@Data
public class FilmeDto {
private String name;
@JsonAlias("characters")
private CharactersDto charactersDto;
}
Oi Marcos,
Eu fiz uma chamada para essa API Graphql e ela devolve um json no seguinte formato:
{
"data":{
"episodesByIds":[
{
"name":"Pilot",
"characters":[
{
"name":"Rick Sanchez"
},
{
"name":"Morty Smith"
},
{
"name":"Bepisian"
},
{
"name":"Beth Smith"
},
{
"name":"Canklanker Thom"
},
{
"name":"Davin"
},
{
"name":"Frank Palicky"
},
{
"name":"Glenn"
},
{
"name":"Hookah Alien"
},
{
"name":"Jerry Smith"
},
{
"name":"Jessica"
},
{
"name":"Jessica's Friend"
},
{
"name":"Mr. Goldenfold"
},
{
"name":"Mrs. Sanchez"
},
{
"name":"Principal Vagina"
},
{
"name":"Summer Smith"
},
{
"name":"Davin"
},
{
"name":"Greebybobe"
},
{
"name":"Pripudlian"
}
]
},
{
"name":"Lawnmower Dog",
"characters":[
{
"name":"Rick Sanchez"
},
{
"name":"Morty Smith"
},
{
"name":"Beth Smith"
},
{
"name":"Bill"
},
{
"name":"Centaur"
},
{
"name":"Creepy Little Girl"
},
{
"name":"Jerry Smith"
},
{
"name":"Melissa"
},
{
"name":"Mr. Goldenfold"
},
{
"name":"Mrs. Pancakes"
},
{
"name":"Scary Brandon"
},
{
"name":"Scary Glenn"
},
{
"name":"Scary Terry"
},
{
"name":"Snuffles (Snowball)"
},
{
"name":"Summer Smith"
},
{
"name":"Scary Teacher"
},
{
"name":"Fido"
},
{
"name":"Accountant dog"
},
{
"name":"Trunkphobic suspenders guy"
}
]
}
]
}
}
Então o retorno da chamada ao método restTemplate.postForEntity
não deve ser um FilmeDto
e sim outro DTO contendo um atributo chamado data, que seria outro DTO, e dentro desse outro teria um atributo chamado episodesByIds sendo que esse sim seria do tipo List<FilmeDto>
.
Ou seja, deve seguir a mesma hierarquia dos dados que forem devolvidos pela API.
Oi Rodrigo, obrigado pelo retorno, vou ajustar a API e testar e retorno no forum.