Giter Club home page Giter Club logo

Comments (5)

byme8 avatar byme8 commented on August 30, 2024 5

Hmm.. Potentially the interface can be even a better way to implement it. I will have a look.

from zeroql.

jenschude avatar jenschude commented on August 30, 2024

I tried something similar with the QueryInfoProvider. But you have to fetch the CallerArgumentExpression in the wrapper method else it will not work:

    public static void Query<TQuery>(Func<TQuery, object> query, [CallerArgumentExpression("query")] string queryKey = "")
    {
        var queryInfo = QueryInfoProvider.Materialize<TQuery>(query, queryKey);
    }

Also the queryKey is never set at runtime, it's important at compile time as the SourceGenerator from ZeroQL analyzes to build the query string and the query store. And retrieve the correct query string at runtime.

Edit: But it didn't worked out nicely. So i resorted to create an extension method which returned custom client with the IHttpHandler

public static class GraphQlClientExtensions
{
    // ReSharper disable once InconsistentNaming
    public static GraphQLClient GraphQLClient(this IClient client, string projectKey)
    {
        return new GraphQLClient(client.ToHandler(projectKey));
    }

    private static IHttpHandler ToHandler(this IClient client, string projectKey)
    {
        return new ClientHandler(client, projectKey);
    }
}

internal class ClientHandler : IHttpHandler
{
    private readonly IClient _client;
    private readonly Uri _graphQlUri;

    public ClientHandler(IClient client, string projectKey)
    {
        _client = client;
        _graphQlUri = new Uri($"/{projectKey}/graphql", UriKind.Relative);
    }

    public void Dispose()
    {
    }

    public async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.RequestUri = _graphQlUri;
        return await _client.SendAsAsync(request, cancellationToken);
    }
}

from zeroql.

byme8 avatar byme8 commented on August 30, 2024

Theoretically, there is a way to make it work. It would require changes in analyzer and it would not look nice.
The QueryAsync would be changed like that:

       public async Task<GraphQLResult<TQueryResult>> QueryAsync<TQueryResult>(string operationName, [GraphQLLambda]Func<Query, TQueryResult> query, [CallerArgumentExpression(nameof(query))] string queryKey = null!)
        {
            var gqlClient = // .. make generated client with our IHttpHandler
            // do other things we need
            var res = await gqlClient.Query(operationName, query, queryKey);
            return res;
        }

and I have a feeling that such implementation would definitely get some sort of unknown WTF.

from zeroql.

jenschude avatar jenschude commented on August 30, 2024

It would already help if there is a way that the analyzers capture classes implementing an interface provided by ZeroQL so libraries could implement it and read the query body from the QueryInfoProvider instead of using the generated ZeroQL client. Would have also the nice side effect to get the tooltips with the compiled query.

This would also ensure that the necessary functionality is supported like variable capturing etc.

from zeroql.

byme8 avatar byme8 commented on August 30, 2024

Checkout v7.0.0-.preview.1. Now it is possible to create wrappers around generated ZeroQL client. Here example:

public static async Task<T?> MakeQuery<T, TQuery, TMutation>(
        GraphQLClient<TQuery, TMutation> client, 
        [GraphQLLambda]Func<TQuery, T> query,
        [CallerArgumentExpression(nameof(query))] string queryKey = "")
        where T : class
{
    var result = await client.Query(query, queryKey: queryKey);
    
    if (result.Errors != null)
    {
        Console.WriteLine("Errors:");
        foreach (var error in result.Errors)
        {
            Console.WriteLine(error.Message);
        }

        return null;
    }
    
    return result.Data;
}

// or like that

public class GraphQLClientWrapper
{
    private readonly TestServerClient client;

    public GraphQLClientWrapper(TestServerClient client)
    {
        this.client = client;
    }

    public async Task<TResult> QueryAsync<TResult>(
        [GraphQLLambda]
        Func<Query, TResult> query,
        [CallerArgumentExpression(nameof(query))]
        string queryKey = "")
        where TResult : class
    {
        var result = await client.Query(query, queryKey: queryKey);

        return result.Data!;
    }
}

Basically new implementation depends on [GraphQLLambda] attribute. Every argument with it will be parsed and converted into query on build.

from zeroql.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.