How to call a GraphQL query/mutation with Java code - java

I know we can use the /graphiql endpoint to test the created or deployed GraphQL API.
I need to consume a GraphQL API which is already there using a Java code. How can I do it.
How can I test a GraphQL end-point using a postman like application, or is it even possible.

Depending on your situation, utilizing Spring RestTemplate might be simplest thing to do.
public class Person {
#JsonProperty("query")
public final String query = "mutation($name:String, $gender:String, $age:Int) { updateDetails (name: $name, gender: $gender, age: $age) }";
#JsonProperty("variables")
public final Map<String, String> variables;
...
}
...
(new RestTemplate()).postForEntity("http://example.com/graphql", new Person("David", "male", 12));
Could go even simpler by avoiding Spring and using HttpClient, building same JSON document using StringBuilder.
Alternatively Apollo Andoid can autogenerate client code for you.

An example, to work for me...
username and password are wrong :) But, URL is ok...
with that, I don't use RestTemplate, any jars, etc..
private static void test_LivePharma() {
try {
URL url = new URL("https://stores-hml.funcionalmais.com/graphql");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-Type", "application/json");
String input="{\"query\":\"mutation{createToken(login:\\\"112233\\\",password:\\\"112233\\\"){ token}}\\n\"}";
OutputStream os = conn.getOutputStream();
os.write(input.getBytes());
os.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

Consuming graphql API in your backend code, will require multiple steps such as.
Defining the schema
Installing the dependencies
Defining the graphql endpoint
import com.coxautodev.graphql.tools.SchemaParser;
import javax.servlet.annotation.WebServlet;
import graphql.servlet.SimpleGraphQLServlet;
#WebServlet(urlPatterns = "/graphql")
public class GraphQLEndpoint extends SimpleGraphQLServlet {
public GraphQLEndpoint() {
super(SchemaParser.newParser()
.file("schema.graphqls") //parse the schema file created earlier
.build()
.makeExecutableSchema());
}
}
Here is a detailed guide to do the same : Graphql-java-backend-implementation
Yes, it is possible to send the request using postman. You can simply copy the schema in the body.
Doing GraphQL request using Postman

Related

Jersey WebTarget vs HTTPURLConnection

I'm learning web services using Java. I'm technically a noob, this is the code I've written, which works, I just don't know which method has what advantage over another, like which one is more secure? Which one will be more faster?
I'm not asking for complete too broad an answer. A short concise one will do.
I've created a REST service using Jersey 2.x and I've created client to consume the said REST service.
POST resource is as follows,
#POST
#Path("postactivity")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public String createActivity(
#QueryParam("id") int id,
#QueryParam("description") String description,
#QueryParam("duration") int duration,
#QueryParam("name")String name)
{
//My code that creates Activity object from QueryParams is here.
}
Now I've created a Client which is a Java Application. I'm consume the above REST Service above in following two ways.
Method 1 Using HTTPURLConnection
private static void doPost(){
QueryString qs = new QueryString("id", "123"); //QueryString is a class created to build query, not important to the question.
qs.add("duration", "12");
qs.add("description", "This is description");
qs.add("name", "This is Name");
String url = "http://localhost:8080/webservices/webapi/activities/activity?" + qs;
URL obj;
try {
obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestProperty("Content-Type","application/json");
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "Mozilla 5.0");
con.setDoOutput(true);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
Activity activity = GSON.fromJson(response.toString(), Activity.class); //This is for checking if i'm getting correct data back which I'm sending.
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Method 2 Using WebTarget available via Jersey
private static void doPost(){
Response entity = webTarget
.path("activities/postactivity")
.queryParam("id",2204)
.queryParam("description","Foo")
.queryParam("duration",100)
.queryParam("name", "Bar")
.request()
.post(null);
String entityRead = entity.readEntity(String.class);
System.out.println(entityRead);
Activity activityRead = GSON.fromJson(entityRead, Activity.class);
}
Thanks.
Honestyl i have two things to write to you:
1. The HttpURLConnection is the Java personal way of doing a retrieve of a web affiliate (like web services) but you have a better and stress-free way of doing it with Jersey and this will make things faster and smoother for you. For some persons they even say that the Jersey style is the High-level API while the HttpURLConnection is called the low-level API.
2. Your question was able to provide me with a necessary solution to a problem i have had for the past two days with consuming a #Queryparam POST webmethod. I really appreciate this.
Thanks

Accessing Spring Rest with 404 error

I am using Spring MVC in my project and while mapping user request to a URI, I get the 404 error. But there are other controllers where i'm able to access it.
Working controller
#RequestMapping(value = "groupview.htm", method = RequestMethod.GET)
public String showGroups(
#ModelAttribute("groupRegistrationDTO") GroupRegistrationDTO groupRegistrationDTO,
BindingResult result, Model model,
HttpServletRequest httpServletRequest) {
GroupsResultDTO groupsResultDTO = manageGroupBusiness.getGroups(
groupRegistrationDTO, result, model);
return "showGroups";
}
Testing with java class showing desired output
private static void wsRequest(String jsonInput) {
try {
URL url = new URL("http://localhost:5080/myservlet/groupview.htm");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept","*/*");
conn.setRequestProperty("Authorization", "Basic "
+ getBasicAuthenticationEncoding());
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Now i have another controller which is a restful service when i try to test that using poster plugin or through java net URL connection(using requestmethod post). I get 404 response code.
Trying to access with URL :
http://localhost:5080/myservlet/authAndRegDevice.htm
Rest Service Controller
#RequestMapping(value = "authAndRegDevice.htm", method = RequestMethod.POST)
#ResponseBody
public String authenticateAndRegisterDevice(
#RequestBody String notificationJsonRequest){
return "success";
}
Why would the second controller give the 404 error while the first one working.
Can some one please help me to get out of this issue
This issue can be closed here as i have raised another post with detailed question and with the exact failure where i was facing.
Bypass spring security with java URL connection

jax-rs returned String

I am programming a jax-rs webservice which I want to contact from a java-program. I defined a #POST method which receives a String-array as input and is supposed to return a boolean value.
But really, how can i access this return value in java? I've been searching the web for several hours now, everybody writes example methods which return Strings or something else, but nobody shows how to access the returned value from another java program.
Here is the code from the program that contacts the #POST method:
ObjectOutputStream oos = null;
String[] login = {"XXXXXX","XXXXXXX"};
try {
login[1] = PasswordGenerator.hashPassword(login[1]);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
URL url = new URL("XXXXX/XXXXXXX/XXXXXX/users/login/1");
try {
// creates a HTTP connection
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
httpConn.setUseCaches(false);
httpConn.setDoOutput(true);
httpConn.setRequestMethod("POST");
httpConn.setRequestProperty("Boolean", "application/xml");
OutputStream outputStream = httpConn.getOutputStream();
oos = new ObjectOutputStream(outputStream);
outputStream.close();
System.out.println();
} finally {
if (oos != null) {
oos.close();
}
}
}
What I want to know is: What happens after I closed my outputStream? I mean, i started the POST method, but it is supposed to return a boolean value. Where is this value? How can I access it???
JAX-RS 2.0 has a Client API that provides you with a fluent API to retrieve the content of the response:
Client client = ClientBuilder.newClient();
Boolean result = client.target("http://localhost:8080/xxx/")
.path("user/login/1")
.request(MediaType.TEXT_PLAIN_TYPE)
.post(Entity.entity(login, MediaType.APPLICATION_XML) , Boolean.class);
But unfortunately, you'll need a custom MessageBodyWriter to convert the String[] into an XML document. Maybe you should change your server-side method (and client) to manipulate a DTO - a POJO with 2 fields, username and password - and annotated with #XmlRootElement ?
something like that:
(client-side)
Credentials credentials = new
credentials.setUsername("foo");
credentials.setUsername("hashedPwd");
Client client = ClientBuilder.newClient();
Boolean result = client.target("http://xxxxx")
.path("/user/login/1")
.request(MediaType.TEXT_PLAIN_TYPE)
.post(Entity.entity(credentials, MediaType.APPLICATION_XML) , Boolean.class);
System.out.println("Result: " + result);
(server-side)
#Path("/login/{id}")
#POST
public Boolean test(#PathParam("id") String login, Credentials credentials) {
...
}

Send and receive JSON to REST WebService in Jersey Java

I am new to Jersey Java REST WebService framework. I am trying to write a service method which consumes and produces JSON. My service code is below. It is simplest code, just for studying purpose.
#Path("/myresource")
public class MyResource {
#Path("/sendReceiveJson")
#GET
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public String sendReceiveJson(String name)
{
System.out.println("Value in name: " + name);
return "{\"serviceName\": \"Mr.Server\"}";
}
}
And following is JerseyClient code.
public class Program {
public static void main(String[] args) throws Exception{
String urlString="http://localhost:8080/MyWebService/webresources/myresource/sendReceiveJson";
URL url=new URL(urlString);
URLConnection connection=url.openConnection();
connection.setDoOutput(true);
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write("{\"clientName\": \"Mr.Client\"}");
out.close();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String decodedString;
while ((decodedString = in.readLine()) != null) {
System.out.println(decodedString);
}
in.close();
}
}
But when i run service and then client, i am unable to send/receive JSON data. I get Exception at connection.getInputStream() which is
Server returned HTTP response code: 405 for URL: http://localhost:8080/hellointernet/webresources/myresource/sendReceiveJson
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1625)
Please guide me, what needs to correct, or whether i am in wrong direction.
Your resource method is annotated as #GET which means any input data would have to be query string parameters.
In this context #Consumes(MediaType.APPLICATION_JSON) doesn't make a lot of sense as only APPLICATION_FORM_URLENCODED is supported via GET.
When you client calls setDoOutput(true) it probably switches your HTTP call to a POST hence causing the 405 Method Not Allowed.
If you want to consume JSON you should change your #GET annotation with #POST instead. Your client call should then work if it's indeed a POST. You can specify it with the following method:
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
httpCon.setDoOutput(true);
httpCon.setRequestMethod("POST");
This API is pretty low level though, so I'd highly recommend you use Jersey's Client API instead. See https://jersey.java.net/documentation/1.17/client-api.html

Google GSON not parsing JSON in Java retrieved from a WebMethod in a C# website

I have an ASP.NET website that uses C# to create JSON via a WebMethod, the webmethod is then called from a Java android application via an http post. I provide the webmethod with a page id and it returns the page contents, in this case it returns the content for an error page.
This is the JSON returned by the webmethod:
D/WebInterface( 2353): {"d":[{"intId":2418,"strName":"Error 404","strTitle":"Ooo
ps, I couldn\u0027t find that!","strSummary":"Error 404, I couldn\u0027t find th
e page you\u0027re looking for.","strBody":"\u003cp\u003eYou could try browsing
the website or checking that you typed the URL correctly, if you came to this pa
ge from another site, please let me know and thanks for visiting.\u003c/p\u003e"
,"strUpdateDate":null,"strCreateDate":null}]}
I use Google GSON in my Android app to create an object from the JSON but it returns null no matter what I do. Here is my Google GSON method:
public static Containerdata resultsFromJson(String json)
{
try
{
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
Containerdata results = gson.fromJson(json, Containerdata.class);
Log.d("WebInterface", "RETURNING OBJECT FROM JSON");
return results;
}
catch(Exception e)
{
Log.d("WebInterface", "Error: Malformed JSON.");
return null;
}
}
This method returns Containerdata which is below:
public class Containerdata {
public List<Containerdata.Node> d;
public class Node
{
int intId;
String strName;
String strTitle;
String strSummary;
String strBody;
String strUpdateDate;
String strCreatedate;
}
}
Containerdata returned by resultsFromJson is always null no matter what I do to the json returned by the webmethod and I have no idea why. This is the method that gets my JSON from my WebMethod:
// Gets json in the form of a string from a web service
public static String dataFromWeb(String url, String postData)
{
Log.d("WebInterface", "Loading from web");
try
{
HttpURLConnection httpcon = (HttpURLConnection) ((new URL(url).openConnection()));
httpcon.setDoOutput(true);
httpcon.setRequestProperty("Content-Type", "application/json");
httpcon.setRequestProperty("Accept", "application/json");
httpcon.setRequestMethod("POST");
httpcon.connect();
byte[] outputBytes = postData.getBytes("UTF-8");
OutputStream os = httpcon.getOutputStream();
os.write(outputBytes);
os.close();
InputStream response = httpcon.getInputStream();
Log.d("WebInterface", Helpers.convertStreamToString(response));
return Helpers.convertStreamToString(response);
}
catch(Exception e)
{
Log.d("WebInterface", "failed from web... " + e.toString());
return "";
}
}
Could anyone please help and point me in the right direction, I'd be very greatful.
Thanks a lot in advance!
The problem is in the following code...
InputStream response = httpcon.getInputStream();
Log.d("WebInterface", Helpers.convertStreamToString(response));
return Helpers.convertStreamToString(response);
You're basically trying to read the InputStream twice. The first time is when you log the response and the second time is when you try to return the response. The problem is you can't read a stream when it has already been read (OK, you can but that requires different code).
If you want to log the response then read the string locally and then log it and return it...
InputStream response = httpcon.getInputStream();
String responseString = Helpers.convertStreamToString(response);
Log.d("WebInterface", responseString);
return responseString;

Categories