taemon
(Tim Stello)
June 18, 2021, 12:46pm
1
Report a Dgraph Client Bug
What Dgraph client (and version) are you using?
(put “x” in the box to select)
Dgo
PyDgraph
Dgraph4J
Dgraph-js
Dgraph-js-http
Dgraph.NET
Version: github.com/dgraph-io/dgo/v210
What version of Dgraph are you using? Slash
Have you tried reproducing the issue with the latest release? yes
What is the hardware spec (RAM, OS)? laptop
Steps to reproduce the issue (command/config used to run Dgraph).
I am trying to make a REST API that talks to a Slash endpoint via the Golang client, it looks like its connecting but is complaining about ‘content-type’ and nothing I have tried or found in other issues seems to make a difference. I’ve tried using both a JWT that is used for Authorizating calls (using Slash @auth ) as well as an API key.
func (dg *Dgraph) Connect() error {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
pool, err := x509.SystemCertPool()
if err != nil {
log.Printf("error getting system certificate store - %s", err)
return err
}
// conn, err := dgo.DialCloud(dg.url, dg.token)
conn, err := grpc.Dial(dg.url, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{RootCAs: pool, ServerName: strings.Split(dg.url, ":")[0]})), grpc.WithPerRPCCredentials(&authorizationCredentials{dg.token}))
if err != nil {
log.Printf("error connecting to Dgraph cloud - %s", err)
return err
}
defer conn.Close()
dgraphClient := dgo.NewDgraphClient(api.NewDgraphClient(conn))
dg.client = dgraphClient
// err = dgraphClient.Login(context.Background(), "user", "passwd")
// if err != nil {
// log.Printf("error logging in: %s", err)
// return err
// }
md := metadata.New(map[string]string{"accept": "application/dql", "content-type": "application/dql"})
ctx = metadata.NewOutgoingContext(ctx, md)
txn := dg.client.NewTxn()
q := `query MyQuery($order: OrderOrder = {}) {
queryOrder(order: $order) {
id
name
price
state
purchased
}
}`
res, err := txn.QueryWithVars(ctx, q, map[string]string{})
if err != nil {
log.Printf("error in query - %s", err)
return err
}
defer txn.Discard(ctx)
log.Printf("ORDERS: %s", string(res.Json))
return nil
}
Expected behaviour and actual result.
Here is the result when I try to connect…
2021/06/18 12:43:16 error in query - rpc error: code = Unauthenticated desc = Unauthorized: HTTP status code 401; transport: missing content-type field
2021/06/18 12:43:16 rpc error: code = Unauthenticated desc = Unauthorized: HTTP status code 401; transport: missing content-type field
exit status 1
make: *** [Makefile:22: grpc] Error 1
dmai
(Daniel Mai)
June 18, 2021, 2:48pm
2
The dgo client currently only supports DQL queries, not GraphQL queries. If you’re looking to make GraphQL queries from Go you can make the HTTP calls to do so or use a GraphQL library. Because Dgraph supports the native GraphQL spec, it works well with GraphQL tools that also support the spec.
1 Like
taemon
(Tim Stello)
June 18, 2021, 5:34pm
3
I keep getting the same error even when trying DQL, do you have an example of a query that returns all records of a certain type “Order” in my example?
p.s. as you may have figured out I’m new to Dgraph
dmai
(Daniel Mai)
June 18, 2021, 6:16pm
4
In DQL you can run a query like this:
{
q(func: type(Order)) {
uid
name
price
state
increased
}
}
taemon
(Tim Stello)
June 18, 2021, 6:49pm
5
Thanks, I couldn’t find a simple example like that in the docs!
Now I have this code:
package dgraph
import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"log"
"strings"
"time"
dgo "github.com/dgraph-io/dgo/v210"
"github.com/dgraph-io/dgo/v210/protos/api"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/metadata"
)
type authorizationCredentials struct {
token string
}
func (a *authorizationCredentials) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
return map[string]string{"Authorization": fmt.Sprintf("Bearer %s", a.token)}, nil
}
func (a *authorizationCredentials) RequireTransportSecurity() bool {
return true
}
func (dg *Dgraph) Connect() error {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
pool, err := x509.SystemCertPool()
if err != nil {
log.Printf("error getting system certificate store - %s", err)
return err
}
// conn, err := dgo.DialCloud(dg.url, dg.token)
conn, err := grpc.Dial(dg.url, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{RootCAs: pool, ServerName: strings.Split(dg.url, ":")[0]})), grpc.WithPerRPCCredentials(&authorizationCredentials{dg.token}))
if err != nil {
log.Printf("error connecting to Dgraph cloud - %s", err)
return err
}
defer conn.Close()
dgraphClient := dgo.NewDgraphClient(api.NewDgraphClient(conn))
dg.client = dgraphClient
// err = dgraphClient.Login(context.Background(), "user", "passwd")
// if err != nil {
// log.Printf("error logging in: %s", err)
// return err
// }
md := metadata.New(map[string]string{"accept": "application/dql", "content-type": "application/dql"})
ctx = metadata.NewOutgoingContext(ctx, md)
txn := dg.client.NewTxn()
q := `{
q(func: type(Order)) {
uid
name
purchased
description
state
}
}`
res, err := txn.Query(ctx, q)
if err != nil {
log.Printf("error in query - %s", err)
return err
}
defer txn.Discard(ctx)
log.Printf("ORDERS: %s", string(res.Json))
return nil
}
which still gives this error:
2021/06/18 18:48:32 error in query - rpc error: code = Unauthenticated desc = Unauthorized: HTTP status code 401; transport: missing content-type field
2021/06/18 18:48:32 rpc error: code = Unauthenticated desc = Unauthorized: HTTP status code 401; transport: missing content-type field
exit status 1
make: *** [Makefile:22: grpc] Error 1
taemon
(Tim Stello)
June 18, 2021, 6:52pm
6
The “dg.token” I am trying to use is both an API key from Slash and also a valid JWT that Slash is configured to authorize using the # Authorization
feature of Slash.
dmai
(Daniel Mai)
June 18, 2021, 7:31pm
7
I see you commented out the dgo.DialCloud
endpoint. Did that not work for you?
You could try setting Authorization
to just the key (not prefixed with "Bearer ") or use the Dg-Auth
instead of Authorization
.
taemon
(Tim Stello)
June 18, 2021, 9:04pm
8
dmai:
Dg-Auth
I will try DialCloud again - it did not work same issue I believe.
taemon
(Tim Stello)
June 18, 2021, 9:11pm
9
Same issue either way, is there some difference in the way Slash authenticates?
I am using the # Authorization
comment to verify the JWT in Slash.
taemon
(Tim Stello)
June 19, 2021, 6:27pm
10
Ok, looks like its working now with DialCloud and generating a new API key!