Skip to content

Commit

Permalink
Merge pull request #18 from nfl/Dynamic_schema_shall_support_multiple…
Browse files Browse the repository at this point in the history
…_fields_of_type_Array_of_External_References

Dynamic schema shall support multiple fields of type Array of External References
  • Loading branch information
sdemchenko authored May 24, 2018
2 parents 2a990c7 + 552e4fd commit 77d83ad
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 23 deletions.
22 changes: 10 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,31 +267,29 @@ the other fields are accepted in the mutation but are ignored. There has not bee
namespaces at this time.

### ExternalReference
Contains a reference to a domain object from another service. Currently, only
Shield domain objects are supported but the implementation could be easily extended
to other services.
Contains a reference to a domain object from another service.

The external reference requires *serviceKey* to be set to _SHIELD_ and
The external reference requires *serviceKey* to be non-empty and
*possibleTypes* set to a collection of anticipated types. *serviceKey* allows for a variety of external services
in the future (such as "WEATHER" which could point to http://weather.gov). Only the value of _SHIELD_ is
currently supported. A Shield example for *possibleTypes*
would be ["Image", "Article", "Video"].
in the future (such as "WEATHER" which could point to http://weather.gov). An example for *possibleTypes*
would be ["Image", "Article", "Video"] etc.

When writing instances of dynamic domain object containing an external reference,
the _id_ is compound one, containing both an *id* field and a *typeDefinition*
field containing one of the configured values from *possibleTypes*. For example, a Hero object having a reference
to a shieldImage do the following upsert mutation:
field containing one of the configured values from *possibleTypes*. For example, a Hero object having an external reference
to Image do the following upsert mutation:
```
{
id: 1234-hero-id,
shieldImage: {
id: 1234-shield-id,
heroHeadshotImage: {
id: 1234-some-id,
typeDefinition: "Image"
}
}
```

Upon the reading the value, the *shieldImage* field would appear to be an embedded shield image object.
Upon the reading the value, the *heroHeadshotImage* field would appear to be an embedded object of an image
as it is define in some GraphQL-based service.

### Struct
Defines a "value" object, one that is stored as part of the dynamic domain
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ maven.central.sync=false
sonatype.username=DUMMY_SONATYPE_USER
sonatype.password=DUMMY_SONATYPE_PASSWORD

PROJECT_VERSION=1.0.10
PROJECT_VERSION=1.0.11
PROJECT_GITHUB_REPO_URL=https://github.com/nfl/gold
PROJECT_LICENSE_URL=https://github.com/nfl/gold/blob/master/LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ private void loadAndValidate(Map<String, Object> initValues) {

@Override
public GraphQLOutputType buildInstanceOutputType(InstanceFieldBuilderContext instanceFieldBuilderContext, InstanceOutputTypeService instanceOutputTypeService) {
return createReferenceOutputType(instanceFieldBuilderContext, instanceOutputTypeService, getParent().getName() + getMemberFieldName() + "ShieldReference");
String typeName = getParent().getName() + getMemberFieldName() + "OutputExternalReference";
if (!instanceFieldBuilderContext.computeOutput(typeName)) {
return new GraphQLTypeReference(typeName);
}
return createReferenceOutputType(instanceFieldBuilderContext, instanceOutputTypeService, typeName);
}

@Override
Expand All @@ -72,6 +76,10 @@ protected GraphQLFieldDefinition.Builder getGraphQLFieldDefinitionBuilder(Instan

@Override
public GraphQLInputType buildInstanceInputType(InstanceFieldBuilderContext instanceFieldBuilderContext) {
String typeName = getParent().getName() + getMemberFieldName() + "InputExternalReference";
if (!instanceFieldBuilderContext.computeOutput(typeName)) {
return new GraphQLTypeReference(typeName);
}
GraphQLInputObjectField idField = newInputObjectField()
.type(new GraphQLNonNull(GraphQLID))
.name(REFERENCE_ID)
Expand All @@ -83,7 +91,7 @@ public GraphQLInputType buildInstanceInputType(InstanceFieldBuilderContext insta
.build();

return GraphQLInputObjectType.newInputObject()
.name(getParent().getName() + getMemberFieldName() + "ExternalReference")
.name(typeName)
.field(idField)
.field(typeDefinition)
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
@SuppressWarnings("WeakerAccess")
public class ListType extends SchemaInstanceField {

private static final String BOGUS_PLACEHOLDER = "BogusPlaceholderToFoolValidation";

public ListType(SchemaDescription parent, Map<String, Object> initValues) {
super(InstanceFieldType.LIST, initValues, parent);

Expand Down Expand Up @@ -100,7 +98,7 @@ public GraphQLInputType buildInstanceInputType(InstanceFieldBuilderContext insta

private Map<String, Object> buildInitValuesMap() {
Map<String, Object> initValues = new HashMap<>();
initValues.put(MEMBER_FIELD_NAME_FIELD, BOGUS_PLACEHOLDER);
initValues.put(MEMBER_FIELD_NAME_FIELD, getMemberFieldName());

switch (getArrayEntryType()) {
case OTHER_DYNAMIC_DOMAIN:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,13 @@ public abstract class BaseExternalReferenceTest extends BaseBeanTest {
@Autowired
private StubbedExternalReferenceRepository externalReferenceRepository;

void loadSchema(String simonSchema, String simonSchemaResults) {
void loadSchema(String schema, String schemaResults) {
// Set up the schema
assertFalse(simonSchema.isEmpty());
GraphQLResult result = graphQLSchemaService.executeQuery(simonSchema,
buildSchemaVariableMap(), buildSchemaWriteAccess());
assertFalse(schema.isEmpty());
GraphQLResult result = graphQLSchemaService.executeQuery(schema, buildSchemaVariableMap(), buildSchemaWriteAccess());
assertTrue(result.isSuccessful());
String actual = result.getData().toString();
Assert.assertEquals(actual, simonSchemaResults);
Assert.assertEquals(actual, schemaResults);
}

GraphQLResult loadErrorSchema(String errorSchema) {
Expand All @@ -46,6 +45,7 @@ public void loadExternalData() {

final String IMAGE_ID = "1234";
final String VIDEO_ID = "5678";
final String AUDIO_ID = "9";

Map<String, Object> imageMap = new HashMap<>();
imageMap.put("id", IMAGE_ID);
Expand All @@ -58,6 +58,13 @@ public void loadExternalData() {
videoMap.put("caption", "The greatest movie ever.");

externalReferenceRepository.loadExternalInstance("Video", VIDEO_ID, videoMap);

Map<String, Object> audioMap = new HashMap<>();
audioMap.put("id", AUDIO_ID);
audioMap.put("title", "Yesterday");
audioMap.put("codec", "FLAC");

externalReferenceRepository.loadExternalInstance("Audio", AUDIO_ID, audioMap);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
public class ExternalReferenceArrayTest extends BaseExternalReferenceTest {

private static final String SIMON = "Simon";
private static final String MULTIPLE_EXT_REF_ARRAYS = "MultipleExtRefArrays";

private final String addSimonArray;
private final String addSimonArrayResults;
Expand All @@ -14,13 +15,24 @@ public class ExternalReferenceArrayTest extends BaseExternalReferenceTest {
private final String viewSimonArray;
private final String viewSimonArrayResults;

private final String addTwoArrays;
private final String addTwoArraysResults;
private final String addTwoArraysInstance;
private final String addTwoArraysInstanceResult;

public ExternalReferenceArrayTest() {
addSimonArray = loadFromFile("graphql/external_reference/add_simon_array.txt");
addSimonArrayResults = loadFromFile("graphql/external_reference/add_simon_array_results.txt");
simonInstanceArrayInstance = loadFromFile("graphql/external_reference/add_simon_array_instance.txt");
addSimonArrayInstanceResult = loadFromFile("graphql/external_reference/add_simon_array_instance_results.txt");
viewSimonArray = loadFromFile("graphql/external_reference/view_simon_array.txt");
viewSimonArrayResults = loadFromFile("graphql/external_reference/view_simon_array_results.txt");


addTwoArrays = loadFromFile("graphql/external_reference/add_two_arrays.txt");
addTwoArraysResults = loadFromFile("graphql/external_reference/add_two_arrays_results.txt");
addTwoArraysInstance = loadFromFile("graphql/external_reference/add_two_arrays_instance.txt");
addTwoArraysInstanceResult = loadFromFile("graphql/external_reference/add_two_arrays_instance_results.txt");
}

public void resolveArrayOfImages() {
Expand All @@ -33,7 +45,14 @@ public void resolveArrayOfImages() {
assertResult(result, viewSimonArrayResults);
}

public void moreThanOneArrayOfExternalReferencesInAGivenSchema() {
// Add an instance with a few fields of type 'Array of External References'
GraphQLResult result = upsert(MULTIPLE_EXT_REF_ARRAYS, addTwoArraysInstance);
assertResult(result, addTwoArraysInstanceResult);
}

void loadSchema() {
loadSchema(addSimonArray, addSimonArrayResults);
loadSchema(addTwoArrays, addTwoArraysResults);
}
}
31 changes: 31 additions & 0 deletions src/test/resources/graphql/external_reference/add_two_arrays.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
mutation {
upsertSchemaDefinition(schemaDef: {
name: "MultipleExtRefArrays",
idGeneration: Client,
domainFields: [{
memberType: Array,
memberFieldName: "shieldRef",
memberDescription: "A pointer to a shield image.",
arrayEntryType: ExternalReference
serviceKey: SHIELD,
possibleTypes: ["Image", "Article", "Video"]
}, {
memberType: Array,
memberFieldName: "audios",
memberDescription: "A pointer to a shield audio.",
arrayEntryType: ExternalReference
serviceKey: SHIELD,
possibleTypes: ["Audio"]
}]
})
{
name,
domainFields {
memberType,
memberFieldName,
memberDescription,
serviceKey,
possibleTypes
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
mutation {
upsertSchemaInstance(schemaInstance: {
id: "Says",
shieldRef:
[{
id: "1234",
typeDefinition: "Image"
},{
id: "5678",
typeDefinition: "Video"
},{
id: "1234",
typeDefinition: "Image"

}],
audios:
[{
id: "9",
typeDefinition: "Audio"
}]
})
{
id,
shieldRef {
... on Image {
id,
title
},
... on Video {
id,
title,
caption
}
},
audios {
... on Audio {
id,
codec
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{upsertSchemaInstance={id=Says, shieldRef=[{id=1234, title=Hitchhikers Guide}, {id=5678, title=Casablanca, caption=The greatest movie ever.}, {id=1234, title=Hitchhikers Guide}], audios=[{id=9, codec=FLAC}]}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{upsertSchemaDefinition={name=MultipleExtRefArrays, domainFields=[{memberType=Array, memberFieldName=shieldRef, memberDescription=A pointer to a shield image., serviceKey=SHIELD, possibleTypes=[Image, Article, Video]}, {memberType=Array, memberFieldName=audios, memberDescription=A pointer to a shield audio., serviceKey=SHIELD, possibleTypes=[Audio]}]}}

0 comments on commit 77d83ad

Please sign in to comment.