Skip to content
This repository has been archived by the owner on Aug 2, 2023. It is now read-only.

Commit

Permalink
feat(GraphQLArgument): introduce optional arguments
Browse files Browse the repository at this point in the history
Extend GraphQLArgument annotation class with field "optional" (default to false for backward compatibility)
Clean "null" stings in valueOf handling of argument values, treat as null reference
Handle optional values in Property query message generation
  • Loading branch information
mkalen committed Nov 1, 2018
1 parent 109d404 commit 234329b
Show file tree
Hide file tree
Showing 13 changed files with 173 additions and 25 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ GraphQLResponseEntity<SampleModel> responseEntity = graphQLTemplate.query(reques

### Annotations to configure fields

#### `@GraphQLArgument(name="name", value="defaultVal", type="String")`
> Used above property fields<br><b>name (required)</b>: GraphQL argument name<br><b>value (optional)</b>: default value to set the argument to<br><b>type (optional)</b>: how to parse the optional value. Accepts an enum of "String", "Boolean", "Integer", or "Float" - defaults to be parsed as a string.<br>You can specify fields arguments directly inline using this. This is good for static field arguments such as result display settings, for instance the format of a date or the locale of a message.
#### `@GraphQLArgument(name="name", value="defaultVal", type="String", optional=false)`
> Used above property fields<br><b>name (required)</b>: GraphQL argument name<br><b>value (optional)</b>: default value to set the argument to<br><b>type (optional)</b>: how to parse the optional value. Accepts an enum of "String", "Boolean", "Integer", or "Float" - defaults to be parsed as a string.<br><b>optional (optional)</b>: set to true if the value is optional and should be left out if value is null - defaults to false.<br>You can specify fields arguments directly inline using this. This is good for static field arguments such as result display settings, for instance the format of a date or the locale of a message.
*example:*
```java
Expand Down
20 changes: 18 additions & 2 deletions nodes/src/main/java/io/aexp/nodes/graphql/Argument.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,29 @@

package io.aexp.nodes.graphql;

public class Argument<T> extends Parameter {
public class Argument<T> extends Parameter<T> {
private boolean optional;

public Argument(String key, T value) {
this(key, value, false);
}

public Argument(String key, T value, boolean optional) {
super(key, value);
this.optional = optional;
}

public boolean isOptional() {
return optional;
}

public void setOptional(boolean optional) {
this.optional = optional;
}

@Override
public String toString() {
return super.toString(this.getClass().getSimpleName());
return super.toString(this.getClass().getSimpleName(),
"optional=" + optional);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -210,14 +210,16 @@ private boolean isProperty(Class clazz) {
*/
private List<Argument> setArgument(List<Argument> arguments, GraphQLArgument graphQLArgument) {
String type = graphQLArgument.type();
boolean optional = graphQLArgument.optional();
String value = valueOf(graphQLArgument.value());
if ("Boolean".equalsIgnoreCase(type)) {
arguments.add(new Argument<Boolean>(graphQLArgument.name(), Boolean.valueOf(graphQLArgument.value())));
arguments.add(new Argument<Boolean>(graphQLArgument.name(), value == null ? null : Boolean.valueOf(value), optional));
} else if ("Integer".equalsIgnoreCase(type)) {
arguments.add(new Argument<Integer>(graphQLArgument.name(), Integer.valueOf(graphQLArgument.value())));
arguments.add(new Argument<Integer>(graphQLArgument.name(), value == null ? null : Integer.valueOf(value), optional));
} else if ("Float".equalsIgnoreCase(type)) {
arguments.add(new Argument<Float>(graphQLArgument.name(), Float.valueOf(graphQLArgument.value())));
arguments.add(new Argument<Float>(graphQLArgument.name(), value == null ? null : Float.valueOf(value), optional));
} else {
arguments.add(new Argument<String>(graphQLArgument.name(), graphQLArgument.value()));
arguments.add(new Argument<String>(graphQLArgument.name(), value, optional));
}
return arguments;
}
Expand Down Expand Up @@ -311,6 +313,13 @@ private Map<String, Property> getChildren(Class clazz, Map<String, Object> prope
return children;
}

private static String valueOf(String value) {
if (value == null || "null".equals(value)) {
return null;
}
return value;
}

public static class RequestBuilder {

URL url = null;
Expand Down
17 changes: 11 additions & 6 deletions nodes/src/main/java/io/aexp/nodes/graphql/Parameter.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,18 @@ public void setValue(T value) {

@Override
public String toString() {
return toString("Parameter");
return toString("Parameter", null);
}

String toString(String name) {
return name + "{" +
"key='" + key + '\'' +
", value=" + value +
'}';
String toString(String name, String extraFields) {
StringBuilder builder = new StringBuilder(name);
builder.append('{');
builder.append("key='").append(key).append('\'');
builder.append(", value=").append(value);
if (extraFields != null) {
builder.append(", ").append(extraFields);
}
builder.append('}');
return builder.toString();
}
}
12 changes: 8 additions & 4 deletions nodes/src/main/java/io/aexp/nodes/graphql/Property.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,17 @@ protected String getMessage(String field) {
}
if (this.resourceName != null) message.append(": ").append(resourceName).append(" ");
if (this.arguments != null && !this.arguments.isEmpty()) {
message.append("(");
List<String> argumentList = new ArrayList<String>();
for (Argument argument: arguments) {
argumentList.add(StringUtil.formatGraphQLParameter(argument.getKey(), argument.getValue()));
if (!argument.isOptional() || argument.getValue() != null) {
argumentList.add(StringUtil.formatGraphQLParameter(argument.getKey(), argument.getValue()));
}
}
if (!argumentList.isEmpty()) {
message.append("(");
message.append(StringUtil.joinStringArray(",", argumentList));
message.append(") ");
}
message.append(StringUtil.joinStringArray(",", argumentList));
message.append(") ");
}
if (children != null && !children.isEmpty()) {
message.append("{ ");
Expand Down
2 changes: 1 addition & 1 deletion nodes/src/main/java/io/aexp/nodes/graphql/Variable.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ public Variable(String key, T value) {

@Override
public String toString() {
return super.toString(this.getClass().getSimpleName());
return super.toString(this.getClass().getSimpleName(), null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@
String name();
String value() default "null";
String type() default "null";
boolean optional() default false;
}
20 changes: 17 additions & 3 deletions nodes/src/test/java/io/aexp/nodes/graphql/ArgumentTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class ArgumentTest {

Expand All @@ -30,7 +31,19 @@ public void argumentStringTest() {
argument.setValue("test");
assertEquals("test", argument.getKey());
assertEquals("test", argument.getValue());
assertEquals("Argument{key='test', value=test}", argument.toString());
assertEquals("Argument{key='test', value=test, optional=false}", argument.toString());
}

@Test
public void argumentOptionalTest() {
Argument argument = new Argument(null, null, false);
argument.setKey("k");
argument.setValue("v");
argument.setOptional(true);
assertEquals("k", argument.getKey());
assertEquals("v", argument.getValue());
assertTrue(argument.isOptional());
assertEquals("Argument{key='k', value=v, optional=true}", argument.toString());
}

@Test
Expand All @@ -40,7 +53,7 @@ public void argumentIntTest() {
argument.setValue(1);
assertEquals("test", argument.getKey());
assertEquals(1, argument.getValue());
assertEquals("Argument{key='test', value=1}", argument.toString());
assertEquals("Argument{key='test', value=1, optional=false}", argument.toString());
}

@Test
Expand All @@ -50,8 +63,9 @@ public void argumentEnumTest() {
argument.setValue(STATUS.active);
assertEquals("test", argument.getKey());
assertEquals(STATUS.active, argument.getValue());
assertEquals("Argument{key='test', value=active}", argument.toString());
assertEquals("Argument{key='test', value=active, optional=false}", argument.toString());
}

@Test
public void argumentInputObjectTest() {
Argument argument = new Argument(null, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ public class ArgumentsTest {
public void argumentsTest() {
Arguments arguments = new Arguments("somePath", new Argument<String>("someKey", "someValue"));
assertEquals("somePath", arguments.getDotPath());
assertEquals("Arguments{dotPath='somePath', arguments=[Argument{key='someKey', value=someValue}]}", arguments.toString());
assertEquals("Arguments{dotPath='somePath', arguments=[Argument{key='someKey', value=someValue, optional=false}]}", arguments.toString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.junit.Test;
import io.aexp.nodes.graphql.models.TestModel;
import io.aexp.nodes.graphql.models.TestModelEnum;
import io.aexp.nodes.graphql.models.TestModelOptionalArguments;
import io.aexp.nodes.graphql.models.TestModelScalar;

import java.math.BigDecimal;
Expand Down Expand Up @@ -57,6 +58,30 @@ public void requestWithoutRequestBody() throws MalformedURLException {
assertEquals("request must be set", exception.getMessage());
}

@Test
public void requestWithOptionalParameter() throws MalformedURLException {
GraphQLRequestEntity requestEntity = GraphQLRequestEntity.Builder()
.url(EXAMPLE_URL)
.request(TestModelOptionalArguments.class)
.arguments(new Arguments("test.nested", new Argument<Integer>("first", 10)))
.build();
requestEntity.setRequestMethod(GraphQLTemplate.GraphQLMethod.QUERY);
assertEquals(EXAMPLE_URL, requestEntity.getUrl().toString());
assertEquals("GraphQLRequestEntity{request='query { test { nested (first:10) { string } } } ', url='"+EXAMPLE_URL+"'}", requestEntity.toString());
}

@Test
public void requestWithOtherOptionalParameter() throws MalformedURLException {
GraphQLRequestEntity requestEntity = GraphQLRequestEntity.Builder()
.url(EXAMPLE_URL)
.request(TestModelOptionalArguments.class)
.arguments(new Arguments("test.nested", new Argument<Integer>("last", 5)))
.build();
requestEntity.setRequestMethod(GraphQLTemplate.GraphQLMethod.QUERY);
assertEquals(EXAMPLE_URL, requestEntity.getUrl().toString());
assertEquals("GraphQLRequestEntity{request='query { test { nested (last:5) { string } } } ', url='"+EXAMPLE_URL+"'}", requestEntity.toString());
}

@Test
public void requestWithEnumInModel() throws MalformedURLException {
GraphQLRequestEntity requestEntity = GraphQLRequestEntity.Builder()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2018 American Express Travel Related Services Company, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/

package io.aexp.nodes.graphql.models;

public class NestedTestModelOptionalArguments {

private String string;

public String getString() {
return string;
}

public void setString(String anotherTestString) {
this.string = anotherTestString;
}

@Override
public String toString() {
return "NestedTestModelOptionalArguments{" +
"string='" + string + '\'' +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2018 American Express Travel Related Services Company, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/

package io.aexp.nodes.graphql.models;

import io.aexp.nodes.graphql.annotations.GraphQLArgument;
import io.aexp.nodes.graphql.annotations.GraphQLArguments;
import io.aexp.nodes.graphql.annotations.GraphQLProperty;

@GraphQLProperty(name = "test")
public class TestModelOptionalArguments {
@GraphQLArguments({
@GraphQLArgument(name = "first", type = "Integer", optional = true),
@GraphQLArgument(name = "last", type = "Integer", optional = true)
})
private NestedTestModelOptionalArguments nested;

public NestedTestModelOptionalArguments getNested() {
return nested;
}

public void setNestedTestModelOptionalArguments(NestedTestModelOptionalArguments nested) {
this.nested = nested;
}

@Override
public String toString() {
return "TestModelOptionalArguments{" + "nested=" + nested + '}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ public void invalidArgumentError() throws GraphQLException, MalformedURLExceptio
exception = e;
}
assertNotNull(exception);
assertEquals("Argument 'Argument{key='test', value=1}' doesn't exist on path 'test'", exception.getMessage());
assertEquals("Argument 'Argument{key='test', value=1, optional=false}' doesn't exist on path 'test'", exception.getMessage());
assertNull(exception.getErrors());
assertEquals("GraphQLException{message='Argument 'Argument{key='test', value=1}' doesn't exist on path 'test'', status='null', description='null', errors=null}", exception.toString());
assertEquals("GraphQLException{message='Argument 'Argument{key='test', value=1, optional=false}' doesn't exist on path 'test'', status='null', description='null', errors=null}", exception.toString());
}
}

0 comments on commit 234329b

Please sign in to comment.