<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: tnodell</title>
    <description>The latest articles on DEV Community by tnodell (@tnodell).</description>
    <link>https://dev.to/tnodell</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1143480%2F078ea776-7e82-4dcd-8cae-86ff148b9981.jpeg</url>
      <title>DEV Community: tnodell</title>
      <link>https://dev.to/tnodell</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tnodell"/>
    <language>en</language>
    <item>
      <title>Creating A New Data Provider In Graphweaver</title>
      <dc:creator>tnodell</dc:creator>
      <pubDate>Tue, 19 Dec 2023 23:40:50 +0000</pubDate>
      <link>https://dev.to/tnodell/creating-a-new-data-provider-in-graphweaver-4bf8</link>
      <guid>https://dev.to/tnodell/creating-a-new-data-provider-in-graphweaver-4bf8</guid>
      <description>&lt;p&gt;Recently I was working on creating a new data provider for &lt;a href="https://graphweaver.com/"&gt;Graphweaver&lt;/a&gt;, our open source tool for connecting multiple data sources. Since there may be others in the future creating a data source from scratch I thought it would be valuable to document the process here. &lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Create a Data Provider
&lt;/h2&gt;

&lt;p&gt;Creating a new data provider requires extending the base graphweaver provider. This defines how data providers interact with Graphweaver. You will need to extend this class to implement your new provider. All of the base data provider methods can be found in &lt;a href="https://graphweaver.com/docs/create-a-data-provider"&gt;these docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This example only implements the &lt;code&gt;find&lt;/code&gt; and &lt;code&gt;findOne&lt;/code&gt; functions, which gets entities and is used on the adminUI on the dashboard and details panel, respectively.&lt;/p&gt;

&lt;p&gt;src/packages/core/src/base-provider.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class Provider&amp;lt;D, G&amp;gt; implements BackendProvider&amp;lt;D, G&amp;gt; {
    constructor(readonly backendId: string) {
        if (!backendId) throw new Error('BackendId must be defined');
    }

    // READ METHODS
    public async find(
        filter: Filter&amp;lt;G&amp;gt;,
        pagination?: PaginationOptions,
        additionalOptionsForBackend?: any
    ): Promise&amp;lt;D[]&amp;gt; {
        throw new Error('Find not implemented.');
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The new provider accepts a generic DataEntity and GraphQLEntity (from graphweaver/core). It will include a private property of your base entity for the service you’re integrating with (more on the base entity and service in a bit). A constructor method with the backendId calls the provider class with the entity that is passed in. You can implement the remaining CRUD methods from the Graphweaver Base Provider. Those methods will call the service that interfaces with the new data source you’re integrating with.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class YourBackendProvider&amp;lt;
  D extends BaseDataEntity,
  G extends GraphQLEntity&amp;lt;D&amp;gt;
&amp;gt; extends Provider&amp;lt;D, G&amp;gt; {
  private entity: YourEntity&amp;lt;D&amp;gt;;

  constructor(backendId: string, entity: YourEntity&amp;lt;D&amp;gt;) {
    super(backendId);
    this.entity = entity;
  }

  public async findOne(filter: Filter&amp;lt;G&amp;gt;): Promise&amp;lt;D | null&amp;gt; {
    const yourService = new YourService(this.entity);
    return yourService.getEntity(String(filter.id));
  }

public async find(filter: Filter&amp;lt;G&amp;gt;): Promise&amp;lt;D[]&amp;gt; {
    const salesforce = new Salesforce(this.entity);
    return salesforce.getEntities(filter);
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Create a Base Data Entity
&lt;/h2&gt;

&lt;p&gt;Now we’ll need to to define the base data entity representing the new data source. This will implement the &lt;code&gt;BaseDataEntity&lt;/code&gt;  type in Graphweaver. The &lt;code&gt;BaseDataEntity&lt;/code&gt; includes methods to determine if the entity is a reference or a collection. &lt;/p&gt;

&lt;p&gt;Your entity will have three properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;new (data: any): D;&lt;/code&gt;&lt;/strong&gt; Any class using this interface must have a constructor that takes some data and returns an instance of your data entity.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;entityName: string;&lt;/code&gt; You must provide a name for the entity&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;getProperties: () =&amp;gt; string;&lt;/code&gt; You must provide a method that gets the properties of the entities and returns them. In this case we return a string that goes into constructing a GraphQL query to our new data source.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your base entity class is an abstract class that implements the above type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export interface YourEntity&amp;lt;D extends YourBase&amp;gt; {
  new (data: any): D;
  entityName: string;
  getProperties: () =&amp;gt; string;
}

export abstract class YourBase implements BaseDataEntity {
  static entityName: string;

  static getProperties() {
    // return what you need to get back data from your new source
   return `
        Id
        Name { value  }
    `;
  }

  public isCollection(fieldName: string, dataField: any) {
    return false;
  }

  public isReference(fieldName: string, dataField: any) {
    return false;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we’ll create an example entity from this base. This entity will be mapped when we return data from our service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt; &lt;span class="nn"&gt;Base&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="s"&gt;"./base"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ExampleEntityData&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;id:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExampleEntity&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;entityName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Example"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//This goes into the GQL request&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;!:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;!:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;constructor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;data:&lt;/span&gt; &lt;span class="nc"&gt;ExampleEntityData&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Create a Service
&lt;/h2&gt;

&lt;p&gt;Now we can implement our connection to our new data source. This service will reference your base entity. It’s up to you to implement the functions that will request data from your data source. In this example let’s make a query to some GraphQL endpoint. When the data returns, we’ll map it to the entity we defined earlier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class YourService&amp;lt;D extends Base&amp;gt; {
  private entity: YourEntity&amp;lt;D&amp;gt;;

  constructor(entity: YourEntity&amp;lt;D&amp;gt;) {
    this.entity = entity;
  }

  public async getEntities(filter: YourFilter&amp;lt;D&amp;gt;) {
    // Get the entities
    const query = `query {
                    result: ${this.entity.entityName}${filter ? constructFilter(filter) : ""} {
                        edges {
                            node {
                                ${this.entity.getProperties()}
                            }
                        }
                    }
        }`;

    const response = await fetch("your-endpoint.com", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json",
        Authorization: `Bearer ${process.env.TOKEN}`,
      },
      body: JSON.stringify({
        query,
      }),
    });

    const data = await response.json();

    // Map new Entities from the data
    return data.map((data) =&amp;gt; {
      return new this.entity({ id: data.id, name: data.name });
    });
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Now you have created a new data integration with Graphweaver. By following these three steps – creating a data provider, defining a base data entity, and implementing the connection to the service – developers can extend Graphweaver's capabilities to integrate with any data source.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>graphql</category>
      <category>api</category>
    </item>
    <item>
      <title>Exploring The Benefits of GraphQL Code Gen</title>
      <dc:creator>tnodell</dc:creator>
      <pubDate>Wed, 23 Aug 2023 00:34:56 +0000</pubDate>
      <link>https://dev.to/tnodell/exploring-the-benefits-of-graphql-code-gen-22gd</link>
      <guid>https://dev.to/tnodell/exploring-the-benefits-of-graphql-code-gen-22gd</guid>
      <description>&lt;p&gt;GraphQL is the leading method of querying APIs in modern web development. Yet, developers face a common challenge using GraphQL: managing the types and structures of the data returned by their queries. Dealing with undefined values and casting partial types to make the Typescript compiler happy is frustrating. Or constructing types for each kind of response. But, there's a solution that alleviates this pain, boosts development speed, and enhances code quality – &lt;a href="https://the-guild.dev/graphql/codegen"&gt;GraphQL Codegen&lt;/a&gt;. This powerful open-source tool automates the generation of code for GraphQL APIs. GraphQL Codegen produces types, queries, and hooks from the GraphQL schema. No more manual repetitive coding or uncertainty about types. In this post, we'll explore how GraphQL Codegen works, and how we use it in our open-source tool &lt;a href="https://github.com/exogee-technology/graphweaver"&gt;Graphweaver&lt;/a&gt; to facilitate a silky smooth developer experience. So let's dive in and uncover how this tool is reshaping the way we build applications.&lt;/p&gt;

&lt;p&gt;When I started using GraphQL as a React developer, one of the things that frustrated me was that I didn’t know the type of data that is being returned from my query. My Typescript types were all empty unless I was casting the type of the response. Which meant I had to maintain a separate types definition file on the frontend. But this did nothing to solve the problem of what was being returned in the query. In the past, a partial solution to this was to use partial types everywhere client side. As a result, we’d have to check for undefined throughout our codebase, losing the benefits of a typing system. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GET_TODOS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="s2"&gt;`
  query getTodos {
    todos {
      id
      description
      assignee {
        id
        firstName
        lastName
      }
    }
  }
`&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GET_TODOS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;todos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Todo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;firstAssigneeFirstName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;assignee&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;firstname&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a couple of gross code smells. First, we have to cast the Todo type because we don’t know what a todo is from the query. The type cast as &lt;code&gt;Partial&amp;lt;Todo&amp;gt;[]&lt;/code&gt; is also a &lt;a href="https://www.typescriptlang.org/docs/handbook/utility-types.html#partialtype"&gt;Partial&lt;/a&gt; which means we also have to handle anything in Todo being missing such as the &lt;code&gt;assignee?&lt;/code&gt;. Alternatively, we could create a new type that explicitly &lt;a href="https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys"&gt;Omits&lt;/a&gt; or &lt;a href="https://www.typescriptlang.org/docs/handbook/utility-types.html#partialtype"&gt;Picks&lt;/a&gt; the exact type returned by the server. But this creates overhead in the form of keeping these types in sync with what’s being requested. Any changes to the query or component cascade into maintaining the correct type.&lt;/p&gt;

&lt;p&gt;The solution is to automatically generate your types from the GraphQL schema, AKA GraphQL Codegen.&lt;/p&gt;

&lt;p&gt;GraphQL Codegen helps automate the process of writing code for GraphQL APIs. By looking at a GraphQL schema we can generate code for our types, queries, and React hooks. This means that developers can save time by not having to manually write repetitive code. GraphQL Codegen also helps with type safety and consistency. It ensures that the code is strongly typed, and can be easily updated when changes are made to the API. This leads to faster development cycles and fewer bugs in production.&lt;/p&gt;

&lt;p&gt;Because GraphQL document fields are already typed, it’s pretty annoying to try to keep your types in sync with them on the client. That’s why GraphQL code generation is so valuable. The gold standard for this process is &lt;a href="https://the-guild.dev/graphql/codegen"&gt;GraphQL Code Generator&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How GraphQL CodeGen Works
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://the-guild.dev/graphql/codegen"&gt;GraphQL Code Generator&lt;/a&gt; is an open-source tool that generates code from your GraphQL schema. It’s highly configurable for your environment with a schema-first approach. The GraphQL schema serves as the contract between the frontend and backend of a GraphQL API. It defines the data types, relationships, and operations that clients can perform on the data. Using this, GraphQL Code Generator can determine the types, queries, and mutations on the frontend.&lt;/p&gt;

&lt;p&gt;Generating the Typescript types from the GraphQL schema occurs in a two-step process. First, GraphQL Codegen looks at the types as defined by the schema. Then it creates a JSON data structure via the introspection query provided by GraphQL. This describes the relationship between your types and queries.&lt;/p&gt;

&lt;p&gt;Using this JSON, GraphQL Codegen creates the Typescript types with a templating engine. This iterates through the custom JSON and creates the types and hooks that your frontend uses.&lt;/p&gt;

&lt;p&gt;In practice, this looks like:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Installing the package&lt;/li&gt;
&lt;li&gt;Setting the configuration&lt;/li&gt;
&lt;li&gt;Executing the Codegen script&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;GraphQL Code Generator can not only create frontend typings but can create the backend resolvers from the GraphQL schema as well. This magic happens in the configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CodegenConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://localhost:4000/graphql&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/**/*.tsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
   &lt;span class="na"&gt;generates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/gql/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;preset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;schema&lt;/code&gt;  identifies the URL for the GraphQL schema endpoint. &lt;code&gt;documents&lt;/code&gt; define where your queries, mutations, arguments etc. are. The &lt;code&gt;generates&lt;/code&gt; key describes the location where your types will output. And the &lt;code&gt;preset&lt;/code&gt; is your template for what kind of output you expect. In GraphQL Code Generator, plugins handle the parsed GraphQL schema and describe the expected output. For example, the &lt;a href="https://the-guild.dev/graphql/codegen/plugins/typescript/typescript"&gt;Typescript plugin&lt;/a&gt; generates the base Typescript types. Presets are groups of plugins for common configurations, such as the &lt;a href="https://the-guild.dev/graphql/codegen/plugins/presets/preset-client"&gt;client preset&lt;/a&gt;, which includes the Typescript plugin. The client preset is configured for optimal usage with React or Vue and for GraphQL clients like urql and Apollo. Presets are opinionated and designed to get you up and running quickly.&lt;/p&gt;

&lt;p&gt;GraphQL Code Generator is a powerful and fast tool for solving the problem of managing types from a GraphQL API. This is not solely limited to frontend web development but can generate your resolvers from the GraphQL schema as well! This approach is schema first, where developers can configure what they want their Codegen to output via a YAML file. The presets and plugins are defined in the YAML file. &lt;/p&gt;

&lt;p&gt;Unfortunately, there are some limitations to having a schema-first approach to creating a GraphQL API. The generated code can be complex and hard to customise, and this philosophy has some inflexibility when custom logic is required that is not supported out of the box by the schema.&lt;/p&gt;

&lt;h2&gt;
  
  
  How We Use GraphQL CodeGen In Graphweaver
&lt;/h2&gt;

&lt;p&gt;We use GraphQL Code Generator in our project Graphweaver. Graphweaver is a open source tool that allows you to connect multiple data sources, from databases, to rest APIs, to Saas Platforms, and expose those as a single GraphQL API. As a part of this process, we generate the GraphQL schema from the data source. From the schema, we then generate the types, queries and hooks for the frontend. Let’s go on a whirlwind tour of how we do this in Graphweaver.&lt;/p&gt;

&lt;p&gt;It all starts with our source of truth in the data source. For this example let's imagine a Postgres database as our datasource. Following up with our Todos example above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Create the Assignees table&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;assignees&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;SERIAL&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;first_name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;last_name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Create the Todos table&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;todos&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;SERIAL&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;assignee_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;FOREIGN&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;assignee_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;assignees&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Insert sample data into Assignees&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;assignees&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'John'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Doe'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Jane'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Smith'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Insert sample data into Todos&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;todos&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;assignee_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Complete project A'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Review documentation'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have a Postgres (or MySQL or SQLite) database with this up and running it’s easy to connect to Graphweaver and generate the entire backend and GraphQL for a project.&lt;/p&gt;

&lt;p&gt;First, initialise the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;npx&lt;/span&gt; &lt;span class="n"&gt;graphweaver&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;latest&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pulls down the latest version of Graphweaver from NPM and starts a new project. The cli will ask you for a name and what kind of database is being used. After you &lt;code&gt;cd&lt;/code&gt;  into the project and install the dependencies you can run another command to generate your backend.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;npm&lt;/span&gt; &lt;span class="n"&gt;graphweaver&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;latest&lt;/span&gt; &lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="n"&gt;postgresql&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;a href="https://graphweaver.com/docs/importing-a-database"&gt;import command line tool&lt;/a&gt; takes the database and does its code generation to create the files for our backend entities and files. Currently, it supports Postgres, MySQL, and SQLite databases. In this case, running the import command opens a database connection to Postgres, fetches the database schema and builds metadata about the database. Then it generates the entity files, schema files, resolver files, and index files. Finally, it closes the connection and logs out what has been created. It’s quite handy to not have to do this manually! A full tutorial on connecting a database can be &lt;a href="https://graphweaver.com/docs/connect-to-a-data-source"&gt;found here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Whether we created this manually or with the import tool, we create the data entities, schema entities, and resolvers. Then you can &lt;code&gt;pnpm start&lt;/code&gt; your project which kicks off the remaining code generation. When you initialise a new Graphweaver instance all the resolvers are passed into Graphweaver. The resolvers contain metadata about the entities and we use this to populate the TypeGraphQL metadata storage. Using this we generate the types, queries, and mutations using GraphQL Code Generation.&lt;/p&gt;

&lt;p&gt;The result of this process entity types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Todo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;__typename&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Todo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Scalars&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ID&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;output&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nl"&gt;description&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;Maybe&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Scalars&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;String&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;output&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;assignee&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;Maybe&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Assignee&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;Maybe&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TodoType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hooks which you can use like any other Apollo hook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;useGetTodosQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;baseOptions&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;Apollo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;QueryHookOptions&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;GetTodosQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GetTodosQueryVariables&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;defaultOptions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;baseOptions&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Apollo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useQuery&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;GetTodosQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GetTodosQueryVariables&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;TodosDocument&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the return types from queries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;GetTodosQueryHookResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;useGetTodosQuery&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So getting back to our original example code. We can rewrite to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GET_TODOS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="s2"&gt;`
  query getTodos {
    todos {
      id
      description
      assignee {
        id
        firstName
        lastName
      }
    }
  }
`&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useGetTodoQuery&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;todos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;firstAssigneeFirstName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;assignee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstname&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where our data.todos are now typed from our React Hook useGetTodoQuery(). We no longer have to cast the type! Although we do have to handle the data itself being undefined during a loading state or error.&lt;/p&gt;

&lt;p&gt;What’s more, is that if we change our query then our types update when we restart the server or have the Graphweaver watch command running. Say we don’t need to see the lastName of the assignee any more, the Graphweaver cli removes that from the response type. A file is generated next to each component &lt;code&gt;./component.generated&lt;/code&gt; which contains the types that the query is using. A complete example of what’s generated can be seen in one of our &lt;a href="https://github.com/exogee-technology/graphweaver/blob/fca019267516a175b47a08d8a7e2a6cd0ec3a96d/src/examples/xero/src/admin-ui/custom-pages/dashboards/single-company/component.generated.ts"&gt;example repos on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With a few commands, Graphweaver generates the backend components, schema, resolvers, and more. As the project progresses, Graphweaver automatically updates types based on query changes, ensuring type consistency. Ultimately, Graphweaver empowers developers to craft APIs that seamlessly amalgamate diverse data sources into a single, cohesive GraphQL interface. This results in a more efficient and structured development experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;GraphQL Codegen is a tool that automates the process of writing code for GraphQL APIs by generating code for types, queries, and hooks from a GraphQL schema. It saves time, improves type safety and consistency, and can be used for both frontend and backend development. While there are limitations to a schema-first approach, we’re using it in Graphweaver to provide a code first solution for developers looking to get started quickly. But we also provide the flexibility to extend their API in any way they can code. We’re big fans of using GraphQL Codegen in our projects. &lt;/p&gt;

&lt;p&gt;Get started using Graphweaver to generate your code from your database with our &lt;a href="https://graphweaver.com/docs"&gt;documentation&lt;/a&gt; to get you &lt;a href="https://graphweaver.com/docs/quick-start"&gt;up and running in under 5 minutes&lt;/a&gt;. If you enjoy Graphweaver &lt;a href="https://github.com/exogee-technology/graphweaver"&gt;please give us a star on GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>typescript</category>
      <category>codegen</category>
      <category>react</category>
    </item>
  </channel>
</rss>
