Anyone using DGraph with its GraphQL API directly connected to the frontend in production?

Pretty much the title… I’m interested how much I can spare me a backend or if I still need one.

Anyone using GraphQL is probably using it on the frontend, so yes, probably everyone. That being, there maybe a backend used for more complex cases on top of that in certain situations. Personally, if I hosted my own backend, I wouldn’t use Dgraph GraphQL, I would use Dgraph DQL, as it is way more powerful.

Hopefully in the next year or so Dgraph GraphQL will be able to handle almost any case DQL can, and be able to handle more standard and complex backend validation cases.

Dgraph Cloud’s purpose is for those of us that don’t want to deal with the hardware end of things.



Haven’t deployed to production since migrating from Elixir/Absinthe to Dgraph, however, it’s 200x less work. There are some things that I’m using middleware for, basically any complex mutations that need to be done inside transactions, but it’s not difficult. I’ve using Sveltekit, so I just create an ‘endpoint’, and execute DQL using the dgraph-js-http lib. Example:

import { dgraphClient } from '$lib/configs/dgraph-client.ts';
import { v4 as uuidv4 } from 'uuid';
import Mux from '@mux/mux-node';

const { Video } = new Mux(import.meta.env.VITE_MUX_TOKEN_ID, import.meta.env.VITE_MUX_TOKEN_SECRET);

export async function post(request) {
  const txn = dgraphClient.newTxn();
  const id = uuidv4();
  const transcriptSlug = request.body.slug;
  let response = {};

  const upload = await Video.Uploads.create({
    cors_origin: import.meta.env.VITE_APP_URL,

    new_asset_settings: {
      passthrough: id,
      playback_policy: 'public',
      mp4_support: 'standard'

  try {
    let videoUpsertJson = {
      query: `{
        var(func: type(Transcript)) @filter(eq(Transcript.slug, \"${transcriptSlug}\")) {
          t as uid
            v as uid
      set: [
          "uid": "uid(v)",
          "dgraph.type": "Video",
          "Video.transcript": { "uid": "uid(t)" },
          "Video.status": 'waiting_for_upload'
          "uid": "uid(t)",
          "": { "uid": "uid(v)" } // Create inverse edge, which only happens automatically in graphql

    const videoRecord = await txn.mutate({ mutation: JSON.stringify(videoUpsertJson) });
    const videoRecordId =;

    await txn.commit();
  } catch(e) {
    if (e === dgraph.ERR_ABORTED) {
    } else {
      throw e;
  } finally {
    await txn.discard();

    return {
      body: {
        url: upload.url
import * as dgraph from "dgraph-js-http"

const clientStub = new dgraph.DgraphClientStub(

const dgraphClient = new dgraph.DgraphClient(clientStub);


export { dgraphClient };

Also for queries that aren’t possible with the standard generate graphql endpoints, you can just create custom queries in the schema that use custom DQL