Different format for inserting data between graphql and dgraph client

Hi, I was testing inserting data into a local dgraph database, and I figured out that the field names varies between via graphql and via dgraph client. The setup I did was:

Schema.graphql


enum PostDataType {
  TEXT
  IMAGE
  VIDEO
  AUDIO
  GIF
}

enum StatusType {
  ACTIVE
  INACTIVE
  BLOCKED
  DELETED
}

type User {
  id: ID!
  createdAt: DateTime!
  updatedAt: DateTime!
  status: StatusType!
  
  firstName: String!
  lastName: String!
  username: String! #@id
  email: String! @id

  posts: [Post!]! @hasInverse(field: by)
}


type Post {
  id: ID!
  createdAt: DateTime!
  updatedAt: DateTime!
  status: StatusType!

  type: PostDataType!
  content: String!
  by: User
  likes: [PostLike] @hasInverse(field: post)
}

type PostLike {
  id: ID!
  createdAt: DateTime!
  updatedAt: DateTime!

  by: User!
  post: Post!
}

Inserting data with graphql

mutation


mutation {
  addUser(
    input: [
      {
        status: ACTIVE
        updatedAt: "2019-10-12T07:20:50.52Z"
        createdAt: "2019-10-12T07:20:50.52Z"
        firstName: "anargu"
        lastName: "anargu"        
        username: "anargu"
        email: "anargu@abc.com"
        posts: []
    }
    ]
  ){
    user{
      id
    }
  }
}

result

{
  "data": {
    "addUser": {
      "user": [
        {
          "id": "0x2"
        }
      ]
    }
  },
  "extensions": {
    "touched_uids": 4
  }
}

Inserting data by dgraph client

type model in go

// Generic struct
type Generic struct {
	Status    string    `json:"status,omitempty"`
	CreatedAt time.Time `json:"createdAt,omitempty"`
	UpdatedAt time.Time `json:"updatedAt,omitempty"`
	DType     []string  `json:"dgraph.type,omitempty"`
}

// Post data model
type Post struct {
	Generic

	ID      string     `json:"uid"`
	Type    string     `json:"type,omitempty"`
	Content string     `json:"content,omitempty"`
	By      User       `json:"by,omitempty"`
	Likes   []PostLike `json:"likes,omitempty"` // Liked User IDs
}

// PostLike model
type PostLike struct {
	Generic
	ID   string `json:"uid,omitempty"`
	By   User   `json:"by,omitempty"`
	Post Post   `json:"post,omitempty"`
}


// User model
type User struct {
	Generic

	ID        string `json:"uid,omitempty"`
	FirstName string `json:"firstName,omitempty"`
	LastName  string `json:"lastName,omitempty"`
	Email     string `json:"email,omitempty"`
	Username  string `json:"username,omitempty"`
	Followers []User `json:"followers,omitempty"`
	Posts     []Post `json:"posts,omitempty"`
}

golang code (it’s a API Rest Endpoint chunk of code)


		v1.POST("/users", func(c *gin.Context) {
			var newUser User
			if err := c.ShouldBindJSON(&newUser); err != nil {
				c.JSON(http.StatusBadRequest, gin.H{
					"Message":     err.Error(),
					"UserMessage": CommonResponseErrorMessage,
				})
				return
			}
			newUser.DType = []string{"User"}

			newUser.Posts = []Post{}

			mu := &api.Mutation{
				CommitNow: true,
			}
			lpb, err := json.Marshal(newUser)
			if err != nil {
				log.Fatal(err)
			}
			mu.SetJson = lpb
			resp, err := dg.NewTxn().Mutate(c, mu)
			if err != nil {
				log.Fatal(err)

				c.JSON(http.StatusInternalServerError, gin.H{
					"err": err.Error(),
				})
			}

			c.JSON(http.StatusOK, gin.H{
				"response": resp,
			})
		})

the request payload for the endpoint is:

{
	"email": "victor@gmail.com",
	"username": "victor"
	
}

it retuned an ok response

query in ratel UI

{
  users(func: type(User)) {
    uid
    username
    User.username
	}
}

result in ratel UI (Just the data field part of the result)


  "data": {
    "postLikes": [],
    "posts": [],
    "users": [
      {
        "uid": "0x2",
        "User.username": "anargu"
      },
      {
        "uid": "0x3",
        "username": "victor"
      }
    ]
  }

As you can see in the result from Ratel, there is a different format data fields is submitted. I have no idea if I skipped a step in the definition of the schema or I forgot to do an extra step but for now It seems to me there is mismatch format (Idk if it’s an issue) how data can be uploaded to database by graphql and/or dgraph client.

I expected that in both ways data will be stored with the same field names.

Any thoughts?

Thanks in advance

That’s how it works. If you have GraphQL as your primary source of truth, it will use the GraphQL model of inserting data. The pattern is, all predicates created via GraphQL will contain the GraphQL Type as a prefix. That’s how it is.

So your query in DQL should be like:

{
  users(func: type(User)) {
    uid
    User.predicate1
    User.predicate2
    User.username
	}
}

So I have to change the structs I made in Go and put their GraphQL types like this:
(prepending the “User.” in each json tag field)


// User model
type User struct {
	Generic
	ID        string `json:"uid,omitempty"`
	FirstName string `json:"User.firstName,omitempty"`
	LastName  string `json:"User.lastName,omitempty"`
	Email     string `json:"User.email,omitempty"`
	Username  string `json:"User.username,omitempty"`
	Followers []User `json:"User.followers,omitempty"`
	Posts     []Post `json:"User.posts,omitempty"`
}

Isn’t it?

In that case, yes. If you gonna use DQL, you have to add the predicate prefix. But you should use a GraphQL client tho. Instead of Dgo.