graphql-client icon indicating copy to clipboard operation
graphql-client copied to clipboard

Configure connection init payload per socket subscription request.

Open machship-bsuryn opened this issue 4 years ago • 1 comments
trafficstars

I have a multi tenant app, and I need to pass through a token per subscription. Currently I am using the ConfigureWebSocketConnectionInitPayload, that sends the appropriate token I require. But this is variable is set per grapqhl connection, is there a way to sett this per CreateSubscriptionStream request? or do I need to have some kind of singleton subscription factory.

GraphQLRequest graphQLRequest = ...
graphQlClient.Options.ConfigureWebSocketConnectionInitPayload = (GraphQLHttpClientOptions x) => { return new Dictionary<string, string>() { 
            ["token"] = "token value"
            }; };
return graphQlClient.CreateSubscriptionStream<T>(graphQLRequest);

machship-bsuryn avatar May 18 '21 03:05 machship-bsuryn

How does your server expect to receive this additional payload?

In my applications im using a custom GraphQLRequest type which adds an additional authorization field to the GraphQL payload, which is then evaluated by the server (graphql-dotnet/server) on a per subscription basis (see discussion here).

my request class looks as follows:

    /// <summary>
    /// A <see cref="GraphQLRequest"/> which handles authorization info
    /// </summary>
    public class AuthGraphQLRequest : GraphQLHttpRequest
    {
        public const string AUTHORIZATION_KEY = "authorization";

        public AuthGraphQLRequest(string query) : base(query)
        {
        }

        public AuthGraphQLRequest(GraphQLRequest request) : base(request.Query)
        {
            OperationName = request.OperationName;
            Variables = request.Variables;
        }

        public string Authorization
        {
            get => !ContainsKey(AUTHORIZATION_KEY) ? null : (string)this[AUTHORIZATION_KEY];
            set => this[AUTHORIZATION_KEY] = value;
        }

        /// <summary>
        /// Moves the Authorization info present in the <see cref="GraphQLHttpClient"/>s Authorization header into the <see cref="Authorization"/> property, so it becomes part of the GraphQL payload.
        /// This should be assigned to <see cref="GraphQLHttpClientOptions.PreprocessRequest"/>
        /// </summary>
        /// <param name="request"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public static Task<GraphQLHttpRequest> PreprocessRequest(GraphQLRequest request, GraphQLHttpClient client)
        {
            if (request is AuthGraphQLRequest ar)
                return Task.FromResult<GraphQLHttpRequest>(ar);

            var authRequest = new AuthGraphQLRequest(request)
            {
                Authorization = client.HttpClient.DefaultRequestHeaders.Authorization?.ToString() ?? ""
            };

            return Task.FromResult<GraphQLHttpRequest>(authRequest);
        }
    }

The PreprocessRequest method is then injected via GraphQLHttpClientOptions:

var graphQlOptions = new GraphQLHttpClientOptions
      {
          EndPoint = "someuri",
          PreprocessRequest = AuthGraphQLRequest.PreprocessRequest
      };

Hope this helps...

rose-a avatar May 18 '21 06:05 rose-a