@@ -424,3 +424,306 @@ meta.add("auth-token", "mySuperSecret")
424424
425425await  dgraphClient .alter (op, meta)
426426``` 
427+ 
428+ ## Browser support  
429+ 
430+ <Note >
431+   The official Dgraph JavaScript gRPC client is designed for Node.js
432+   environments and doesn't officially support browser usage due to gRPC-web
433+   limitations and bundling complexities. However, you can achieve ** most**  of
434+   the same capabilities in browsers using Dgraph's HTTP API with standard
435+   ` fetch `  requests.
436+ </Note >
437+ 
438+ <Tip >
439+   If you only need basic CRUD operations and don't require admin endpoints (like
440+   schema alterations or dropping data), consider using Dgraph's GraphQL API
441+   instead, which is designed for client-side usage and provides better security
442+   boundaries.
443+ </Tip >
444+ 
445+ <Warning >
446+   We don't recommend connecting directly to Dgraph from browser applications as
447+   this could expose your database credentials and connection details to end
448+   users. Consider using a backend API as a proxy instead.
449+ </Warning >
450+ 
451+ ### Node.js gRPC vs browser HTTP API  
452+ 
453+ Below are side-by-side examples showing how to perform common operations using
454+ both the Node.js gRPC client and browser-compatible HTTP requests.
455+ 
456+ #### Creating a connection  
457+ 
458+ ** Node.js (gRPC):** 
459+ 
460+ ``` js 
461+ const  dgraph  =  require (" dgraph-js" 
462+ const  grpc  =  require (" grpc" 
463+ 
464+ const  clientStub  =  new  dgraph.DgraphClientStub (
465+   " localhost:9080" 
466+   grpc .credentials .createInsecure (),
467+ )
468+ const  dgraphClient  =  new  dgraph.DgraphClient (clientStub)
469+ ``` 
470+ 
471+ ** Browser (HTTP):** 
472+ 
473+ ``` js 
474+ const  DGRAPH_HTTP_URL  =  " http://localhost:8080" 
475+ 
476+ //  Test connection to Dgraph
477+ const  response  =  await  fetch (` ${ DGRAPH_HTTP_URL } ` 
478+ if  (! response .ok ) {
479+   throw  new  Error (` Cannot connect to Dgraph: ${ response .status } ` 
480+ }
481+ console .log (" Connected to Dgraph successfully" 
482+ ``` 
483+ 
484+ #### Setting schema  
485+ 
486+ ** Node.js (gRPC):** 
487+ 
488+ ``` js 
489+ const  schema  =  " name: string @index(exact) ." 
490+ const  op  =  new  dgraph.Operation ()
491+ op .setSchema (schema)
492+ await  dgraphClient .alter (op)
493+ ``` 
494+ 
495+ ** Browser (HTTP):** 
496+ 
497+ ``` js 
498+ const  schema  =  " name: string @index(exact) ." 
499+ 
500+ await  fetch (` ${ DGRAPH_HTTP_URL } ` 
501+   method:  " POST" 
502+   headers:  { " Content-Type" :  " application/rdf" 
503+   body:  schema,
504+ })
505+ ``` 
506+ 
507+ #### Running queries  
508+ 
509+ ** Node.js (gRPC):** 
510+ 
511+ ``` js 
512+ const  query  =  ` query all($a: string) {
513+   all(func: eq(name, $a)) { 
514+     name 
515+   } 
516+ }`  
517+ const  vars  =  { $a:  " Alice" 
518+ const  res  =  await  dgraphClient .newTxn ().queryWithVars (query, vars)
519+ const  data  =  res .getJson ()
520+ ``` 
521+ 
522+ ** Browser (HTTP):** 
523+ 
524+ ``` js 
525+ const  query  =  ` query all($a: string) {
526+   all(func: eq(name, $a)) { 
527+     name 
528+   } 
529+ }`  
530+ const  vars  =  { $a:  " Alice" 
531+ 
532+ const  response  =  await  fetch (` ${ DGRAPH_HTTP_URL } ` 
533+   method:  " POST" 
534+   headers:  { " Content-Type" :  " application/json" 
535+   body:  JSON .stringify ({ query, variables:  vars }),
536+ })
537+ const  data  =  await  response .json ()
538+ ``` 
539+ 
540+ #### Running mutations  
541+ 
542+ ** Node.js (gRPC):** 
543+ 
544+ ``` js 
545+ const  txn  =  dgraphClient .newTxn ()
546+ try  {
547+   const  p  =  { name:  " Alice" :  26  }
548+   const  mu  =  new  dgraph.Mutation ()
549+   mu .setSetJson (p)
550+   mu .setCommitNow (true )
551+   await  txn .mutate (mu)
552+ } finally  {
553+   await  txn .discard ()
554+ }
555+ ``` 
556+ 
557+ ** Browser (HTTP):** 
558+ 
559+ ``` js 
560+ const  p  =  { name:  " Alice" :  26  }
561+ 
562+ await  fetch (` ${ DGRAPH_HTTP_URL } ` 
563+   method:  " POST" 
564+   headers:  { " Content-Type" :  " application/json" 
565+   body:  JSON .stringify ({ set:  [p] }),
566+ })
567+ ``` 
568+ 
569+ #### Upsert operations  
570+ 
571+ ** Node.js (gRPC):** 
572+ 
573+ ``` js 
574+ const  query  =  ` query {
575+   user as var(func: eq(email, "[email protected] ")) 576+ }`  
577+ 
578+ const  mu  =  new  dgraph.Mutation ()
579+ mu .
setSetNquads (
` uid(user) <email> "[email protected] " .` )
580+ 
581+ const  req  =  new  dgraph.Request ()
582+ req .setQuery (query)
583+ req .setMutationsList ([mu])
584+ req .setCommitNow (true )
585+ 
586+ await  dgraphClient .newTxn ().doRequest (req)
587+ ``` 
588+ 
589+ ** Browser (HTTP):** 
590+ 
591+ ``` js 
592+ const  query  =  ` query {
593+   user as var(func: eq(email, "[email protected] ")) 594+ }`  
595+ 
596+ await  fetch (` ${ DGRAPH_HTTP_URL } ` 
597+   method:  " POST" 
598+   headers:  { " Content-Type" :  " application/json" 
599+   body:  JSON .stringify ({
600+     query:  query,
601+     set
:  [{ uid
:  " uid(user)" , email
:  " [email protected] "  }],
602+   }),
603+ })
604+ ``` 
605+ 
606+ #### Conditional upserts  
607+ 
608+ ** Node.js (gRPC):** 
609+ 
610+ ``` js 
611+ const  query  =  ` query {
612+   user as var(func: eq(email, "[email protected] ")) 613+ }`  
614+ 
615+ const  mu  =  new  dgraph.Mutation ()
616+ mu .
setSetNquads (
` uid(user) <email> "[email protected] " .` )
617+ mu .setCond (` @if(eq(len(user), 1))` 
618+ 
619+ const  req  =  new  dgraph.Request ()
620+ req .setQuery (query)
621+ req .addMutations (mu)
622+ req .setCommitNow (true )
623+ 
624+ await  dgraphClient .newTxn ().doRequest (req)
625+ ``` 
626+ 
627+ ** Browser (HTTP):** 
628+ 
629+ ``` js 
630+ const  query  =  ` query {
631+   user as var(func: eq(email, "[email protected] ")) 632+ }`  
633+ 
634+ await  fetch (` ${ DGRAPH_HTTP_URL } ` 
635+   method:  " POST" 
636+   headers:  { " Content-Type" :  " application/json" 
637+   body:  JSON .stringify ({
638+     query:  query,
639+     mutations:  [
640+       {
641+         set
:  [{ uid
:  " uid(user)" , email
:  " [email protected] "  }],
642+         cond:  " @if(eq(len(user), 1))" 
643+       },
644+     ],
645+   }),
646+ })
647+ ``` 
648+ 
649+ #### Drop all data  
650+ 
651+ ** Node.js (gRPC):** 
652+ 
653+ ``` js 
654+ const  op  =  new  dgraph.Operation ()
655+ op .setDropAll (true )
656+ await  dgraphClient .alter (op)
657+ ``` 
658+ 
659+ ** Browser (HTTP):** 
660+ 
661+ ``` js 
662+ await  fetch (` ${ DGRAPH_HTTP_URL } ` 
663+   method:  " POST" 
664+   headers:  { " Content-Type" :  " application/json" 
665+   body:  JSON .stringify ({ drop_all:  true  }),
666+ })
667+ ``` 
668+ 
669+ #### Authentication  
670+ 
671+ ** Node.js (gRPC):** 
672+ 
673+ ``` js 
674+ const  meta  =  new  grpc.Metadata ()
675+ meta .add (" auth-token" " mySuperSecret" 
676+ await  dgraphClient .alter (op, meta)
677+ ``` 
678+ 
679+ ** Browser (HTTP):** 
680+ 
681+ ``` js 
682+ await  fetch (` ${ DGRAPH_HTTP_URL } ` 
683+   method:  " POST" 
684+   headers:  {
685+     " Content-Type" :  " application/rdf" 
686+     " auth-token" :  " mySuperSecret" 
687+   },
688+   body:  schema,
689+ })
690+ ``` 
691+ 
692+ ### Browser-specific considerations  
693+ 
694+ #### Connection strings  
695+ 
696+ For convenience, you can parse connection strings similar to database URLs:
697+ 
698+ ``` js 
699+ function  parseDgraphUrl (connectionString ) {
700+   if  (connectionString .startsWith (" http" 
701+     return  { url:  connectionString, headers:  {} }
702+   }
703+ 
704+   //  Handle dgraph://user:pass@host:port format
705+   const  url  =  new  URL (connectionString .replace (" dgraph://" " https://" 
706+   const  headers  =  {}
707+ 
708+   if  (url .username  &&  url .password ) {
709+     headers[" Authorization" = 
710+       ` Basic ${ btoa (` ${ url .username } ${ url .password } ` } ` 
711+   }
712+ 
713+   return  {
714+     url:  ` http://${ url .hostname } ${ url .port  ||  8080 } ` 
715+     headers,
716+   }
717+ }
718+ 
719+ //  Usage
720+ const  { url , headers  } =  parseDgraphUrl (" dgraph://user:pass@localhost:8080" 
721+ const  DGRAPH_HTTP_URL  =  url
722+ ``` 
723+ 
724+ ### Limitations of HTTP API  
725+ 
726+ -  ** No streaming** : HTTP doesn't support gRPC streaming capabilities
727+ -  ** Transaction isolation** : HTTP requests are stateless; use upserts for
728+   consistency
729+ -  ** Performance** : Higher overhead compared to persistent gRPC connections
0 commit comments