This is an automated email from the ASF dual-hosted git repository.

bdelacretaz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git


The following commit(s) were added to refs/heads/master by this push:
     new 04c602a  GraphiQL client-side queries work
04c602a is described below

commit 04c602ab741d6905aec4afdd64e000a824dc066f
Author: Bertrand Delacretaz <bdelacre...@apache.org>
AuthorDate: Thu May 28 16:11:13 2020 +0200

    GraphiQL client-side queries work
---
 org.apache.sling.graphql.samples.website/README.md | 57 ++++++++++++++++----
 .../datafetchers/ArticlesWithTextFetcher.java      | 63 ++++++++++++++++++++++
 .../samples/website/datafetchers/FetcherUtil.java  | 48 +++++++++++++++++
 .../datafetchers/SamplesDataFetcherProvider.java   |  2 +
 .../website/datafetchers/SeeAlsoDataFetcher.java   | 14 ++++-
 .../apps/samples/servlet/GQLschema.jsp             | 25 +++++++++
 .../features/feature-graphql-example-website.json  |  4 +-
 7 files changed, 200 insertions(+), 13 deletions(-)

diff --git a/org.apache.sling.graphql.samples.website/README.md 
b/org.apache.sling.graphql.samples.website/README.md
index c8b4b94..a353235 100644
--- a/org.apache.sling.graphql.samples.website/README.md
+++ b/org.apache.sling.graphql.samples.website/README.md
@@ -3,7 +3,17 @@ Apache Sling GraphQL demo website
 
 This is a work in progress demo of the Sling GraphQL Core.
 
-## Status
+It demonstrates both server-side GraphQL queries, used for content 
aggregation, and the 
+more traditional client-side queries, using the same GraphQL schemas and data 
fetching
+Java components for both variants.
+
+Besides the page rendering code there's not much: GraphQL schema definitions 
and a few
+Java classes used for aggregating or enhancing content and for content queries.
+
+For now there's no pagination of query results, just arbitrary limits on the 
number
+of results returned.
+
+## Demo Website
 
 A website with rich navigation is implemented with server-side GraphQL queries 
and client-side
 Handlebars templates for HTML rendering.
@@ -12,16 +22,45 @@ http://localhost:8080/content/graphql-website-demo.html is 
the entry point, afte
 this as described below.
 
 The rendering is based on JSON content that's aggregated server-side using 
GraphQL queries
-to provide all the page content, navigation etc. in a single request.</p>
+to provide all the page content, navigation etc. in a single request.
+
+This is just an initial prototype. As a next step I'd like to render the 
article pages using
+server-side Handlebars templates and implement a few single-page applications 
for search
+and browsing. While keeping the articles rendering server-side (so that they 
make sense
+for Web search engines for example) and ideally using the same languages 
(GraphQL and
+Handlebars) either server- or client-side.
+
+## Client-side GraphQL queries
+
+Client-side queries work using an external GraphiQL client (or any suitable 
client) that
+talks to http://localhost:8080/graphql.json
+
+For now only simple queries are supported, like:
+
+    {
+      article(withText: "jacobi") {
+        path
+        title
+        tags
+        seeAlso {
+          title
+          path
+        }
+      }
+    }
 
-This is just an initial prototype. I'd like to move closer to
-[Progressive Web 
Apps](https://en.wikipedia.org/wiki/Progressive_web_application) techniques, 
-generating a basic rendering server-side and enhancing it with CSS and 
JavaScript
-client-side.
+Besides fixing the `DataFetcher`s to use the correct context Resource, setting 
this up
+only required activating the `GraphQLServlet` (in the Feature Model that 
starts this demo)
+and adding the below schema file. Everything else is shared between the 
server-side and 
+client-side query variants.
 
-The GraphQL schemas and `DataFetchers` that have been implemented will be 
usable for more
-traditional client-side GraphQL queries as well, once that's setup. As that 
side of things has
-less unknowns, I'm focusing on the less usual server-side GraphQL concepts for 
now.
+    # /apps/samples/servlet/GQLschema.jsp
+    type Query {
+      ## fetch:samples/articlesWithText
+      article (withText : String) : [Article]
+    }
+    
+    <%@include file="/apps/samples/common/GQLschema.jsp" %>
 
 ## How to run this
 
diff --git 
a/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/ArticlesWithTextFetcher.java
 
b/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/ArticlesWithTextFetcher.java
new file mode 100644
index 0000000..8005a0e
--- /dev/null
+++ 
b/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/ArticlesWithTextFetcher.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.sling.graphql.samples.website.datafetchers;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.graphql.samples.website.models.SlingWrappers;
+
+import graphql.schema.DataFetcher;
+import graphql.schema.DataFetchingEnvironment;
+
+class ArticlesWithTextFetcher implements DataFetcher<Object> {
+
+    public static final String NAME = "articlesWithText";
+    public static final String P_WITH_TEXT = "withText";
+
+    private final Resource resource;
+
+    ArticlesWithTextFetcher(Resource resource) {
+        this.resource = resource;
+    }
+
+    @Override
+    public Object get(DataFetchingEnvironment environment) throws Exception {
+        final String expectedText = environment.getArgument(P_WITH_TEXT);
+        final String jcrQuery = String.format(
+            "/jcr:root/content/articles//*[jcr:contains(@text, '%s') or 
jcr:contains(@title, '%s')]",
+            expectedText, expectedText);
+
+        final List<Map<String, Object>> result = new ArrayList<>();
+        final Iterator<Resource> it = 
resource.getResourceResolver().findResources(jcrQuery, "xpath");
+        // TODO should use pagination
+        int counter = 451;
+        while(it.hasNext()) {
+            if(--counter <= 0) {
+                break;
+            }
+            result.add(SlingWrappers.resourceWrapper(it.next()));
+        }
+        return result;
+    }
+}
\ No newline at end of file
diff --git 
a/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/FetcherUtil.java
 
b/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/FetcherUtil.java
new file mode 100644
index 0000000..514feba
--- /dev/null
+++ 
b/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/FetcherUtil.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.sling.graphql.samples.website.datafetchers;
+
+import java.util.Map;
+
+import org.apache.sling.api.resource.Resource;
+import graphql.schema.DataFetchingEnvironment;
+
+class FetcherUtil {
+
+    /** Return the "source" Resource to use, preferably the one provided
+     *  by the DataFetchingEnvironment, otherwise the supplied base Resource.
+     */
+    static Resource getSourceResource(DataFetchingEnvironment env, Resource 
base) {
+        Resource result = base;
+        String path = null;
+        final Object o = env.getSource();
+        if(o instanceof Map) {
+            final Map<?, ?> m = (Map)o;
+            path = String.valueOf(m.get("path"));
+        }
+        if(path != null) {
+            final Resource r = base.getResourceResolver().getResource(base, 
path);
+            if(r != null) {
+                result = r;
+            }
+        }
+        return result;
+    }
+}
\ No newline at end of file
diff --git 
a/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/SamplesDataFetcherProvider.java
 
b/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/SamplesDataFetcherProvider.java
index b6b6739..850efac 100644
--- 
a/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/SamplesDataFetcherProvider.java
+++ 
b/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/SamplesDataFetcherProvider.java
@@ -46,6 +46,8 @@ public class SamplesDataFetcherProvider implements 
DataFetcherProvider {
             return new ArticlesBySectionFetcher(r);
         } else if(NavigationDataFetcher.NAME.equals(name)) {
             return new NavigationDataFetcher(r);
+        } else if(ArticlesWithTextFetcher.NAME.equals(name)) {
+            return new ArticlesWithTextFetcher(r);
         }
         return null;
     }
diff --git 
a/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/SeeAlsoDataFetcher.java
 
b/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/SeeAlsoDataFetcher.java
index e863761..ecd9722 100644
--- 
a/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/SeeAlsoDataFetcher.java
+++ 
b/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/SeeAlsoDataFetcher.java
@@ -54,13 +54,23 @@ class SeeAlsoDataFetcher implements DataFetcher<Object> {
         return result;
     }
 
+    private String getSourcePath(DataFetchingEnvironment env) {
+        String result = null;
+        final Object o = env.getSource();
+        if(o instanceof Map) {
+            final Map<?, ?> m = (Map)o;
+            result = String.valueOf(m.get("path"));
+        }
+        return result;
+    }
+
     @Override
-    public Object get(DataFetchingEnvironment environment) throws Exception {
+    public Object get(DataFetchingEnvironment env) throws Exception {
 
         // Our "see also" field only contains node names - this demonstrates
         // using a query to get their full paths
         // 
-        final ValueMap vm = resource.adaptTo(ValueMap.class);
+        final ValueMap vm = FetcherUtil.getSourceResource(env, 
resource).adaptTo(ValueMap.class);
         if(vm != null) {
             return Arrays
                 .stream(vm.get(NAME, String[].class))
diff --git 
a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/servlet/GQLschema.jsp
 
b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/servlet/GQLschema.jsp
new file mode 100644
index 0000000..2c8e0de
--- /dev/null
+++ 
b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/servlet/GQLschema.jsp
@@ -0,0 +1,25 @@
+<%-- 
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you 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.
+--%>
+
+type Query {
+  ## fetch:samples/articlesWithText
+  article (withText : String) : [Article]
+}
+
+<%@include file="/apps/samples/common/GQLschema.jsp" %>
\ No newline at end of file
diff --git 
a/org.apache.sling.graphql.samples.website/src/main/resources/features/feature-graphql-example-website.json
 
b/org.apache.sling.graphql.samples.website/src/main/resources/features/feature-graphql-example-website.json
index de1ad43..816323a 100644
--- 
a/org.apache.sling.graphql.samples.website/src/main/resources/features/feature-graphql-example-website.json
+++ 
b/org.apache.sling.graphql.samples.website/src/main/resources/features/feature-graphql-example-website.json
@@ -10,7 +10,7 @@
       "id" : "org.apache.sling:org.apache.sling.graphql.core:0.0.1-SNAPSHOT",
       "configurations" : {
         "org.apache.sling.graphql.core.GraphQLServlet~default" : {
-          "sling.servlet.resourceTypes" : "graphql/servlet",
+          "sling.servlet.resourceTypes" : "samples/servlet",
           "sling.servlet.extensions": "json",
           "sling.servlet.methods": [ "GET", "POST" ]
         }
@@ -41,7 +41,7 @@
     "allow   jcr:read on /graphql",
     "end",
     "set properties on /graphql",
-    "set sling:resourceType{String} to graphql/servlet",
+    "set sling:resourceType{String} to samples/servlet",
     "end"
   ]
 }
\ No newline at end of file

Reply via email to