Issue
First time trying out GraphQL, so please excuse if it is a basic fix.
https://i.stack.imgur.com/Hwf8Q.png
My API is used to show some mock data of departures from Heathrow. The API should return all the departures which are displayed in the import.sql file. This is running a h2 in memory DB using Spring. My application.properites:
spring.h2.console.enabled=true
spring.h2.console.path=/h2
spring.datasource.url=jdbc:h2:mem:lhrdata
graphql.servlet.mapping=/graphql
graphql.servlet.enabled=true
graphql.servlet.corsEnabled=true
graphiql.enabled=true
graphiql.endpoint=/graphql
graphiql.mapping=graphiql
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.defer-datasource-initialization=true
Entity > Departure.java
package com.LHRDepartures.LHROUT.entity;
import javax.persistence.*;
import java.util.Arrays;
import java.util.List;
@Entity
public class Departure {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String destination;
private Float arrival_time;
private String airline;
private String aircraft_make;
private String aircraft_model;
private String terminal;
public Departure() {
}
public Departure(Long id, String destination, Float arrival_time, String airline, String aircraft_make, String aircraft_model, String terminal) {
this.id = id;
this.destination = destination;
this.arrival_time = arrival_time;
this.airline = airline;
this.aircraft_make = aircraft_make;
this.aircraft_model = aircraft_model;
this.terminal = terminal;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
public Float getArrival_time() {
return arrival_time;
}
public void setArrival_time(Float arrival_time) {
this.arrival_time = arrival_time;
}
public String getAirline() {
return airline;
}
public void setAirline(String airline) {
this.airline = airline;
}
public String getAircraft_make() {
return aircraft_make;
}
public void setAircraft_make(String aircraft_make) {
this.aircraft_make = aircraft_make;
}
public String getAircraft_model() {
return aircraft_model;
}
public void setAircraft_model(String aircraft_model) {
this.aircraft_model = aircraft_model;
}
public String getTerminal() {
return terminal;
}
public void setTerminal(String terminal) {
this.terminal = terminal;
}
}
Mutator
package com.LHRDepartures.LHROUT.mutator;
import com.LHRDepartures.LHROUT.entity.Departure;
import com.LHRDepartures.LHROUT.exception.DepartureNotFoundException;
import com.LHRDepartures.LHROUT.repository.DepartureRepository;
import com.coxautodev.graphql.tools.GraphQLMutationResolver;
import org.springframework.stereotype.Component;
import java.util.Optional;
public class Mutation implements GraphQLMutationResolver {
private DepartureRepository departureRepository;
public Mutation(DepartureRepository departureRepository){
this.departureRepository = departureRepository;
}
public boolean deleteDeparture(Long ID){
departureRepository.deleteById(ID);
return true;
}
/*
public Departure updateTerminal(Integer newTerminal, Long Id){
Optional<Departure> optionalDeparture =
departureRepository.findById(Id);
if(optionalDeparture.isPresent()){
Departure departure = optionalDeparture.get();
// departureRepository.setName(newTerminal);
departureRepository.save(departure);
return departure;
} else {
throw new DepartureNotFoundException("Departure not found!", Id);
} */
}
Repository
package com.LHRDepartures.LHROUT.repository;
import com.LHRDepartures.LHROUT.entity.Departure;
import org.springframework.data.repository.CrudRepository;
public interface DepartureRepository extends CrudRepository<Departure, Long> {
}
Query
package com.LHRDepartures.LHROUT.resolver;
import com.LHRDepartures.LHROUT.entity.Departure;
import com.LHRDepartures.LHROUT.repository.DepartureRepository;
import org.springframework.stereotype.Component;
@Component
public class Query {
private DepartureRepository departureRepository;
public Query(DepartureRepository departureRepository){
this.departureRepository = departureRepository;
}
public Iterable<Departure> findAllDepartures() {
return departureRepository.findAll();
}
}
Service
package com.LHRDepartures.LHROUT.service;
import com.LHRDepartures.LHROUT.entity.Departure;
import org.springframework.stereotype.Service;
import java.util.List;
public interface DepartureService {
List<Departure> retrieveDeparture();
}
Controller
package com.LHRDepartures.LHROUT.web;
import com.LHRDepartures.LHROUT.entity.Departure;
import com.LHRDepartures.LHROUT.service.DepartureService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class DepartureController {
private DepartureService departureService;
@Autowired
public void setDepartureService(DepartureService departureService){
this.departureService = departureService;
}
@GetMapping("/departure")
public ResponseEntity<List<Departure>> getAllDeparture(){
List<Departure> list = departureService.retrieveDeparture();
return new ResponseEntity<List<Departure>>(list, HttpStatus.OK);
}
}
GraphQL schema:
type Departure{
id: ID!
destination : String!
arrival_time : Float!
airline : String!
aircraft_make : String
aircraft_model : String
terminal : String!
}
type Query {
findAllDepartures: [Departure]
}
type Mutation {
deleteDeparture(id:ID) : Boolean
updateTerminal(newTerminal : String, id:ID!): Departure!
}
Import.sql
INSERT INTO departure (id, destination, arrival_time, airline, aircraft_make, aircraft_model, terminal) VALUES (1, 'LAX - Los Angeles Intl.', '1234', 'British Airways', 'AIRBUS', 'A380', '5');
INSERT INTO departure (id, destination, arrival_time, airline, aircraft_make, aircraft_model, terminal) VALUES (2, 'JFK - New York John F. Kennedy Intl.', '1345', 'British Airways', 'BOEING', '777-300', '5');
INSERT INTO departure (id, destination, arrival_time, airline, aircraft_make, aircraft_model, terminal) VALUES (3, 'MAN - Manchester Intl.', '1400', 'British Airways', 'AIRBUS', 'A319', '5');
INSERT INTO departure (id, destination, arrival_time, airline, aircraft_make, aircraft_model, terminal) VALUES (4, 'FRA - Frankfurt Intl.', '1521', 'Lufthansa', 'AIRBUS', 'A319', "3');
INSERT INTO departure (id, destination, arrival_time, airline, aircraft_make, aircraft_model, terminal) VALUES (5, 'CPT - Cape Town Intl.', '1605', 'Virgin Atlantic', 'BOEING', '787-900', '2');
INSERT INTO departure (id, destination, arrival_time, airline, aircraft_make, aircraft_model, terminal) VALUES (6, 'LAX - Los Angeles Intl.', '1634', 'British Airways', 'BOEING', '777-300', '5');
I know there's a lot there, but I'm quite stuck. Any help appreciated.
Solution
At the moment you have no code that will glue your graphql server and business logic together.
Fortunately, Spring boot provides seamless integration GraphQL integration with their Spring Boot for GraphQL project.
In order to start using it, just add the following dependency to your build tool.
implementation 'org.springframework.boot:spring-boot-starter-graphql'
Then, you need to add your schema to the following place:
resources/graphql/schema.graphqls
Your schema definition looks good, so it will work when added into this place
Lastly, you need to define a Controller which will bind your business logic to the graphql server.
import com.example.graphql.departure.model.Departure;
import com.example.graphql.departure.model.DepartureRepository;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;
@Controller
public class DepartureController {
private final DepartureRepository departureRepository;
public DepartureController(DepartureRepository departureRepository) {
this.departureRepository = departureRepository;
}
@QueryMapping
public Iterable<Departure> findAllDepartures() {
return departureRepository.findAll();
}
}
Check how @QueryMapping annotation is used in order to define a valid graphql query.
Then, if you run everything, you should be able to see the results.
Take a look at this sample project for a reference https://github.com/CaptainAye/graphql-sample
Answered By - CaptainAye
Answer Checked By - Candace Johnson (JavaFixing Volunteer)