예제 #1
0
        public GraphQLAzureFunctionsMiddlewareProxy(
            IRequestExecutorResolver graphqlExecutorResolver,
            IHttpResultSerializer graphqlResultSerializer,
            IHttpRequestParser graphqlRequestParser,
            NameString schemaName = default
            )
        {
            //We support multiple schemas by allowing a name to be specified, but default to DefaultName if not.
            this.SchemaName = schemaName.HasValue ? schemaName : Schema.DefaultName;

            //Validate Dependencies...
            this.ExecutorResolver = graphqlExecutorResolver ??
                                    throw new ArgumentNullException(nameof(graphqlExecutorResolver), GRAPHQL_MIDDLEWARE_INIT_ERROR);

            this.ResultSerializer = graphqlResultSerializer ??
                                    throw new ArgumentNullException(nameof(graphqlResultSerializer), GRAPHQL_MIDDLEWARE_INIT_ERROR);

            this.RequestParser = graphqlRequestParser ??
                                 throw new ArgumentNullException(nameof(graphqlRequestParser), GRAPHQL_MIDDLEWARE_INIT_ERROR);


            //BBernard - Initialize the middleware proxy and pipeline with support for both Http GET & POST processing...
            //NOTE: Middleware uses the Pipeline Pattern (similar to Chain Of Responsibility), therefore
            //  we adapt that here to manually build up the two key middleware handlers for Http Get & Http Post processing.
            var httpGetMiddlewareShim = new HttpGetMiddleware(
                (httpContext) => throw new HttpRequestException(
                    "GraphQL was unable to process the request, ensure that an Http POST or GET GraphQL request was sent as well-formed Json."
                    ),
                this.ExecutorResolver,
                this.ResultSerializer,
                this.RequestParser,
                this.SchemaName
                );

            ////NOTE: The normal use case for GraphQL is POST'ing of the query so we initialize it last in the chain/pipeline
            ////  so that it is the first to execute, and then fallback to Http Get if appropriate, finally throw
            ////  an exception if neither are supported by the current request.
            this.MiddlewareProxy = new HttpPostMiddleware(
                async(httpContext) => await httpGetMiddlewareShim.InvokeAsync(httpContext),
                this.ExecutorResolver,
                this.ResultSerializer,
                this.RequestParser,
                this.SchemaName
                );
        }
        private MiddlewareBase ConfigureMiddlewareChainOfResponsibility()
        {
            //*********************************************
            //Manually Build the Proxy Pipeline...
            //*********************************************
            this.MiddlewareProxyDelegate = (httpContext) => throw new HttpRequestException(
                                                     "GraphQL was unable to process the request, ensure that an Http POST or GET GraphQL request was sent as well-formed Json."
                                                     );

            //BBernard - Initialize the middleware proxy and pipeline with support for both Http GET & POST processing...
            //NOTE: Middleware uses the Pipeline Pattern (e.g. Chain Of Responsibility), therefore
            //  we adapt that here to manually build up the key middleware handlers for Http Get & Http Post processing.
            //NOTE: Other key features such as Schema download and the GraphQL IDE (Banana Cake Pop Dynamic UI) are all
            //      delivered by other Middleware also.
            //NOTE: Middleware MUST be configured in the correct order of dependency to support the functionality and
            //          the chain of responsibility is executed inside-out; or last registered middleware will run first and
            //          the first one registered will run last (if not already previously handled).
            //      Therefore we MUST register the middleware in reverse order of how the HC Core code does in the
            //          `public static GraphQLEndpointConventionBuilder MapGraphQL()` builder logic.
            //      Proper Execution Order must be:
            //          - HttpPostMiddleware
            //          - HttpGetSchemaMiddleware
            //          - ToolDefaultFileMiddleware
            //          - ToolOptionsFileMiddleware
            //          - ToolStaticFileMiddleware
            //          - HttpGetMiddleware

            if (Options.EnableGETRequests)
            {
                var httpGetMiddlewareShim = new HttpGetMiddleware(
                    this.MiddlewareProxyDelegate,
                    this.ExecutorResolver,
                    this.ResultSerializer,
                    this.RequestParser,
                    this.SchemaName
                    );
                this.MiddlewareProxyDelegate = (httpContext) => httpGetMiddlewareShim.InvokeAsync(httpContext);
            }

            if (Options.EnableBananaCakePop)
            {
                var toolStaticFileMiddlewareShim = new ToolStaticFileMiddleware(
                    this.MiddlewareProxyDelegate,
                    this.FileProvider,
                    this.RoutePath
                    );
                this.MiddlewareProxyDelegate = (httpContext) => toolStaticFileMiddlewareShim.Invoke(httpContext);

                var toolOptionsFileMiddlewareShim = new ToolOptionsFileMiddleware(
                    //New for v12 The Constructor for this Middleware is simplified and no longer requires the injection of GraphQL dependencies because it's simply a File Handler for BCP
                    this.MiddlewareProxyDelegate,
                    this.RoutePath
                    );
                this.MiddlewareProxyDelegate = (httpContext) => toolOptionsFileMiddlewareShim.Invoke(httpContext);

                var toolDefaultFileMiddlewareShim = new ToolDefaultFileMiddleware(
                    this.MiddlewareProxyDelegate,
                    this.FileProvider,
                    this.RoutePath
                    );
                this.MiddlewareProxyDelegate = (httpContext) => toolDefaultFileMiddlewareShim.Invoke(httpContext);
            }

            if (Options.EnableSchemaDefinitionDownload)
            {
                var httpGetSchemaMiddlewareShim = new HttpGetSchemaMiddleware(
                    this.MiddlewareProxyDelegate,
                    this.ExecutorResolver,
                    this.ResultSerializer,
                    this.SchemaName,
                    //New v12 parameter set to Integrated to enable integrated/default functionality (compatible with v11 behavior).
                    MiddlewareRoutingType.Integrated
                    );
                this.MiddlewareProxyDelegate = (httpContext) => httpGetSchemaMiddlewareShim.InvokeAsync(httpContext);
            }

            ////NOTE: The normal use case for GraphQL is POST'ing of the query so we initialize it last in the chain/pipeline
            ////  so that it is the first to execute, and then fallback to Http Get if appropriate, finally throw
            ////  an exception if neither are supported by the current request.
            var httpPostMiddlewareShim = new HttpPostMiddleware(
                this.MiddlewareProxyDelegate,
                this.ExecutorResolver,
                this.ResultSerializer,
                this.RequestParser,
                this.SchemaName
                );

            this.MiddlewareProxyDelegate = (httpContext) => httpPostMiddlewareShim.InvokeAsync(httpContext);

            //RETURN the Post Middleware as the Primary Middleware reference...
            return(httpPostMiddlewareShim);
        }