Breaking

Friday, October 29, 2021

GraphQL–Strawberry Shake GraphQL client

Until recently I always used the GraphQL.Client as the GraphQL client of my choice. This client is straightforward and easy-to-use.

For a new project I decided to give Strawberry Shake a try. Strawberry Shake was created by Chilicream, the creators of the HotChocolate GraphQL backend for .NET.

Strawberry Shake is using a different approach as the GraphQL.Client as it heavily relies on code generation and looks similar to the Apollo GraphQL client from a design point of view.

I mostly followed the “Get started” documentation to get the Strawberry Shake client up and running, but I didn’t get everything up and running immediatelly so I’ll add some extra detail on the points where I got into trouble.

Add the CLI tools

  • We start by adding the Strawberry Shake CLI tools
  • Open the folder that contains the project where you want to add the Strawberry Shake GraphQL client.
  • Now wee need to first create a dotnet tool-manifest.

dotnet new tool-manifest

Getting ready...

The template "Dotnet local tool manifest file" was created successfully.

  • After doing that we can install the Strawberry Shake tools locally.

dotnet tool install StrawberryShake.Tools –local

You can invoke the tool from this directory using the following commands: 'dotnet tool run dotnet-graphql' or 'dotnet dotnet-graphql'.

Tool 'strawberryshake.tools' (version '12.0.1') was successfully installed. Entry is added to the manifest file C:\projects\graphqlclientexample\.config\dotnet-tools.json.

Add the NuGet packages

  • Now we need to add some NuGet packages:

dotnet add package StrawberryShake.Transport.Http

dotnet add package StrawberryShake.CodeGeneration.CSharp.Analyzers

dotnet add package Microsoft.Extensions.DependencyInjection

dotnet add package Microsoft.Extensions.Http

Add the GraphQL client

  • Next step is to add a client using the following command  dotnet graphql init {{ServerUrl}} -n {{ClientName}}.

dotnet graphql init https://example.graphql.be/graphql/ -n ExampleClient

Download schema started.

Download schema completed in 399 ms

Client configuration started.

Client configuration completed in 137 ms

  •  A .graphqlrc.json is generated together with a schema.graphql file and a schema.extensions.graphql file:

    {
    "schema": "schema.graphql",
    "documents": "**/*.graphql",
    "extensions": {
    "strawberryShake": {
    "name": "ExampleClient",
    "url": "https://example.graphql.be/graphql/",
    "dependencyInjection": true,
    "strictSchemaValidation": true,
    "hashAlgorithm": "md5",
    "useSingleFile": true,
    "requestStrategy": "Default",
    "outputDirectoryName": "Generated",
    "noStore": false,
    "emitGeneratedCode": true,
    "razorComponents": false,
    "records": {
    "inputs": false,
    "entities": false
    },
    "transportProfiles": [
    {
    "default": "Http",
    "subscription": "WebSocket"
    }
    ]
    }
    }
    }
    view raw .graphqlrc.json hosted with ❤ by GitHub

    Add a GraphQL query

    • At this moment no code is generated yet. Therefore we have to write our first graphql query.
    • Create a new .graphql file and write the query you want to execute
    query GetProducts {
    products {
    name
    price
    }
    }
    • The next step mentioned in the documentation is that you only need to compile your code to let the code generation do its work. But nothing happened when I tried to do that.
    • I discovered that I had to take one extra step. I needed to set the build action for the graphql file to GraphQL compiler:

    • Now when I build my code a Generated folder appears containing an ExampleClient. StrawberryShake.cs file.
    • Register the generated client in your Startup.cs file:
    services
    .AddExampleClient()
    .ConfigureHttpClient(client => client.BaseAddress = new Uri("https://example.graphql.be/graphql/"));
    view raw Startup.cs hosted with ❤ by GitHub

    Use the generated query

    • To use the query I first need to inject the generated client:
    public class ProductService
    {
    private readonly IExampleClient _client;
    public ProductService(IExampleClient client)
    {
    _client=client;
    }
    }
    • Then I can invoke the query in a type safe manner:
    public async Task<IList<Product>> GetProducts()
    {
    var result= _client.GetProducts.ExecuteAsync();
    return result.Data.Products;
    }
    view raw GetProducts.cs hosted with ❤ by GitHub

    No comments:

    Post a Comment