GraphQL APIs
REST es la manera más conocida de proporcionar datos de un servidor, aunque sus respuestas son muy rígidas. GraphQL es un lenguaje de queries para APIs, que al igual que REST es usado para cargar datos de un servidor a un cliente, pero que es muy eficiente y flexible porque permite al cliente especificar exactamente lo que necesita.
Para integrar GraphQL en Spring Boot estas librerías son necesarias (deben añadirse manualmente):
Además de Postman y otras herramientas del estilo, disponemos de GraphiQL para testear nuestra GraphQL API.
Location.java
LocationNotFoundException
Mutation.java
LocationRepository.java
Query.java
LocationService.java
LocationServiceImpl.java
LocationController.java
Para integrar GraphQL en Spring Boot estas librerías son necesarias (deben añadirse manualmente):
- graphql-spring-boot-starter - Este starter es muy útil porque configura automáticamente un Servlet GraphQL al que puedes acceder a través de /graphql.
- graphql-java-tools - Una librería de ayuda para parsear el esquema de GraphQL.
GraphQL schema (.graphqls)
Define los data points que ofrece la API. Incluye los tipos de datos, las relaciones entre ellos y las operaciones que podemos realizar sobre ellos.type Location {
id: ID!
name: String!
address: String!
}
type Query {
findAllLocations: [Location]!
}
type Mutation {
newLocation(name: String!, address: String) : Location!
deleteLocation(id:ID!) : Boolean
updateLocationName(newName: String!, id:ID!) : Location!
}
Operations
Las operaciones que GraphQL ofrece sobre los datos son:- Queries: nos permiten obtener datos. Cada query tendra su propio objeto.
- Mutations: podemos actualizar la información almacenada en el servidor (Create, Update y Delete).
{
"query": {findAllLocations {name id address} }"
}
Además de Postman y otras herramientas del estilo, disponemos de GraphiQL para testear nuestra GraphQL API.
Ejemplo:
Location.java
@Entity
public class Location {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String address;
public Location(Long id, String name, String address) {
this.id = id;
this.name = name;
this.address = address;
}
public Location(String name, String address) {
this.name = name;
this.address = address;
}
public Location() {}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
LocationNotFoundException
public class LocationNotFoundException extends RuntimeException implements GraphQLError {
private Map<String, Object> extensions = new HashMap<>();
public LocationNotFoundException(String message, Long invalidLocationId) {
super(message);
extensions.put("invalidLocationId", invalidLocationId);
}
@Override
public List<SourceLocation> getLocations() {
return null;
}
@Override
public Map<String, Object> getExtensions() {
return extensions;
}
@Override
public ErrorType getErrorType() {
return ErrorType.DataFetchingException;
}
}
Mutation.java
@Component
public class Mutation implements GraphQLMutationResolver {
private LocationRepository locationRepository;
public Mutation(LocationRepository locationRepository) {
this.locationRepository = locationRepository;
}
public Location newLocation(String name, String address) {
Location location = new Location(name, address);
locationRepository.save(location);
return location;
}
public boolean deleteLocation(Long id) {
locationRepository.deleteById(id);
return true;
}
public Location updateLocationName(String newName, Long id) {
Optional<Location> optionalLocation =
locationRepository.findById(id);
if(optionalLocation.isPresent()) {
Location location = optionalLocation.get();
location.setName(newName);
locationRepository.save(location);
return location;
} else {
throw new LocationNotFoundException("Location Not Found", id);
}
}
}
LocationRepository.java
public interface LocationRepository extends CrudRepository {
}
Query.java
@Component
public class Query implements GraphQLQueryResolver {
private LocationRepository locationRepository;
public Query(LocationRepository locationRepository) {
this.locationRepository = locationRepository;
}
public Iterable<Location> findAllLocations() {
return locationRepository.findAll();
}
}
LocationService.java
public interface LocationService {
List retrieveLocations();
}
LocationServiceImpl.java
@Service
public class LocationServiceImpl implements LocationService {
@Autowired
LocationRepository locationRepository;
public List<Location> retrieveLocations() {
return (List<Location>) locationRepository.findAll();
}
}
LocationController.java
@RestController
public class LocationController {
private LocationService locationService;
@Autowired
public void setLocationService(LocationService locationService) {
this.locationService = locationService;
}
@GetMapping("/location")
public ResponseEntity<List<Location>> getAllLocations() {
List<Location> list = locationService.retrieveLocations();
return new ResponseEntity<List<LocationGlt;>(list, HttpStatus.OK);
}
}
Comentarios
Publicar un comentario