open-source-labs / obsidian

GraphQL, built for Deno - a native GraphQL caching client and server module

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Client Usage Without React?

zicklag opened this issue · comments

Is there a way to use the obsidian client without needing react? I'm wanting to use it for an API client in a server-side application.

Hi there! Unfortunately the client currently only exists as a React component, so it cannot be used independently of React. That said, the destructuring and normalization algorithms were developed independently of the Router or Client, so with a little work it is feasible to implement this functionality. Paging @mmeigs, @CaliskanBurak, and @Alonsog66 - happy to help implement this with one of you.

Hey @TravisFrankMTG, thanks for your quick response! I'm still looking around and feeling out what I should use for a client so I'm not 100% sure I'd end up using Obsidian even if it had this feature. I was just needing a GraphQL client and Obsidian looks like it might be more useful as a full SSR solution. Just a warning so you don't implement this feature just because I needed it and then I don't end up using it. 😉

Hey @TravisFrankMTG, thanks for your quick response! I'm still looking around and feeling out what I should use for a client so I'm not 100% sure I'd end up using Obsidian even if it had this feature. I was just needing a GraphQL client and Obsidian looks like it might be more useful as a full SSR solution. Just a warning so you don't implement this feature just because I needed it and then I don't end up using it. 😉

What did you end up using for GraphQL client in Deno? I'm also looking for one and haven't found any working solution yet.

@borsemayur2 What features do you need in the GraphQL client? If you just need to send simple requests you can do that through simple HTTP requests without any dedicated GQL client.

I realized that, like @dsymiller said, if you're just posting to a GraphQL API similar to how you would normally use a REST API, you don't really need any special client libraries. Still a wrapper over raw HTTP POST's was very useful for including the JWT I needed for auth, etc. Here's the script I ended up using. Hasura was the GraphQL endpoint that I was talking to, thus the naming, but other than the constructor there's nothing that makes it specific:

export class HasuraClient {
  private hasuraEndpoint: string;


  constructor({ hasuraUrl }: { hasuraUrl: string }) {
    this.hasuraEndpoint = hasuraUrl + "/v1/graphql";
  }


  /**
   * Call a GraphQL query or mutation.
   *
   * > Note: Throws an exception of there are any HTTP or GraphQL errors.
   *
   * @param query The GraphQL query to execute
   * @param variables The GraphQL variables to add to the query
   */
  async call(
    query: string,
    jwt?: string,
    // deno-lint-ignore no-explicit-any
    variables?: { [key: string]: any }
    // deno-lint-ignore no-explicit-any
  ): Promise<any> {
    const headers: Record<string, string> = {
      "content-type": "application/json",
    };
    if (jwt) {
      headers["Authorization"] = "Bearer " + jwt;
    }


    const resp = await fetch(this.hasuraEndpoint, {
      method: "POST",
      headers,
      body: JSON.stringify({
        query,
        variables,
      }),
    });


    if (!resp.ok) {
      console.error("HTTP Error:", resp);
      throw resp;
    }


    const data = await resp.json();


    if (data.errors) {
      console.error("GraphQL Error:", data);
      throw data;
    }


    return data;
  }
}

Also, a nifty trick, if you have the Apollo VSCode plugin you can use this shim to get syntax highlighting and formatting for your GraphQL queries:

/** A GQL tag shim for improving IDE support for inline GraphQL queries */
export const gql = (data: TemplateStringsArray) => data[0];

Then you can use the thing like this:

const hasuraClient = new HasuraClient({
  hasuraUrl: HASURA_URL,
});

const resp = await hasuraClient.call(
    gql`
      query Upload($id: uuid!) {
        upload: uploads_by_pk(id: $id) {
          id
        }
      }
    `,
    jwt,
    {
      id: ctx.params.id,
    }
  );

Thanks @zicklag @dsymiller . Will try both.

As this is outside the scope of Obsidian at the moment, closing this issue. Thanks for the discussion, all!