From 4d96cfbf6b7a8d34906150481e9d3a5543a1db38 Mon Sep 17 00:00:00 2001 From: Nepomuk Seiler Date: Thu, 26 Jul 2018 08:44:17 +0200 Subject: [PATCH] Enable post requests for introspection (#41) * Enable post requests for introspection * Scalafmt --- README.md | 6 +++ .../muki/graphql/schema/SchemaLoader.scala | 46 ++++++++++++++++--- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 4128154..d2dcedf 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,12 @@ graphqlProductionSchema := GraphQLSchemaLoader .fromIntrospection("http://prod.your-graphql.net/graphql", streams.value.log) .withHeaders("X-Api-Version" -> "1", "X-Api-Key" -> "4198ab84-e992-42b0-8742-225ed15a781e") .loadSchema() + +// from a graphql endpoint via introspection with post request +graphqlProductionSchema := GraphQLSchemaLoader + .fromIntrospection("http://prod.your-graphql.net/graphql", streams.value.log) + .withPost() + .loadSchema() ``` diff --git a/src/main/scala/rocks/muki/graphql/schema/SchemaLoader.scala b/src/main/scala/rocks/muki/graphql/schema/SchemaLoader.scala index 125ce06..06a1927 100644 --- a/src/main/scala/rocks/muki/graphql/schema/SchemaLoader.scala +++ b/src/main/scala/rocks/muki/graphql/schema/SchemaLoader.scala @@ -76,7 +76,9 @@ class FileSchemaLoader(file: File) extends SchemaLoader { */ case class IntrospectSchemaLoader(url: String, log: Logger, - headers: Seq[(String, String)] = Seq.empty) + headers: Seq[(String, String)] = Seq.empty, + method: IntrospectSchemaLoader.Method = + IntrospectSchemaLoader.GET) extends SchemaLoader { override def loadSchema(): Schema[Any, Any] = @@ -86,22 +88,52 @@ case class IntrospectSchemaLoader(url: String, copy(headers = headers.toList) } + /** + * @return a new schema loader that uses a POST requests instead of a get request + */ + def withPost(): IntrospectSchemaLoader = { + copy(method = IntrospectSchemaLoader.POST) + } + /** * @see https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js * @return the introspect query result */ private def introspect(): Json = { - log.info(s"Introspect graphql endpoint: $url") - val response = Http(url) - .headers(headers) - .param("query", introspectionQuery.renderCompact) - .asString + log.info(s"Introspect graphql endpoint: ${method.name} : $url") + + val response = method match { + case IntrospectSchemaLoader.POST => + val body = Json + .obj("query" -> Json.fromString(introspectionQuery.renderCompact)) + .noSpaces + Http(url).headers(headers).method("POST").postData(body).asString + case IntrospectSchemaLoader.GET => + Http(url) + .headers(headers) + .param("query", introspectionQuery.renderCompact) + .asString + } + parse(response.body) match { case Right(json) => json case Left(error) => log.error("JSON parse errors:") log.error(error.message) - sys.error(s"Invalid JSON was returned from graphql endpoint $url") + log.error("Body received") + log.error(response.body) + sys.error( + s"Invalid JSON was returned from graphql endpoint ${method.name} : $url") } } } + +object IntrospectSchemaLoader { + + /** + * http method for introspection query + */ + sealed abstract class Method(val name: String) + case object POST extends Method("POST") + case object GET extends Method("GET") +}