Skip to content

Latest commit

 

History

History
193 lines (173 loc) · 3.93 KB

06.object.md

File metadata and controls

193 lines (173 loc) · 3.93 KB

Object

a schema used to resolve fields into a struct or map.

Simple

Example: a schema that resolves the data of a User struct.

schema := gq.Object[User]{
	Name:        "User",
	Description: "...",
	Fields: gq.Fields{
		"id": gq.Field{
			Type: gq.String{},
		},
		"name": gq.Field{
			Type: gq.String{},
		},
		"email": gq.Field{
			Type: gq.String{},
		},
		"created_at": gq.Field{
			Type: gq.Date{},
		},
		"updated_at": gq.Field{
			Type: gq.Date{},
		},
	},
}

res := schema.Do(&gq.DoParams{
	Query: "{id,name,email}",
	Value: User{
		ID: "1",
		Name: "test",
		Email: "[email protected]",
		CreatedAt: time.Now(),
		UpdatedAt: time.Now(),
	},
})

if res.Error != nil {
	panic(res.Error)
}

Nested

you can add fields that resolve data not present on the Object, which can be used to create virtual properties or join on relational data.

Example: we add a new field resolver to our first example, allowing you to query the created_by field.

schema := gq.Object[User]{
	Name:        "User",
	Description: "...",
	Fields: gq.Fields{
		"id": gq.Field{
			Type: gq.String{},
		},
		"name": gq.Field{
			Type: gq.String{},
		},
		"email": gq.Field{
			Type: gq.String{},
		},
		"created_at": gq.Field{
			Type: gq.Date{},
		},
		"updated_at": gq.Field{
			Type: gq.Date{},
		},
		"created_by_id": gq.Field{
			Type: gq.String{},
		},
		"created_by": gq.Field{
			Type: gq.Object[*User]{
				Name: "User.CreatedBy",
				Fields: gq.Fields{
					"id": 	gq.Field{
						Type: gq.String{},
					},
					"name":	gq.Field{
						Type: gq.String{},
					},
				},
			},
			Description: "the user that created this user",
			DependsOn: []string{"created_by_id"}, // ensure `created_by_id` field resolves before this does.
			Resolver: func(params *gq.ResolveParams) gq.Result {
				user := params.Parent.(User)
				createdBy := // fetch user somehow
				return gq.Result{Data: &createdBy}
			},
		},
	},
}

res := schema.Do(&gq.DoParams{
	Query: "{id,name,email,created_by{id,name}}",
	Value: User{
		ID: "1",
		Name: "test",
		Email: "[email protected]",
		CreatedAt: time.Now(),
		UpdatedAt: time.Now(),
	},
})

if res.Error != nil {
	panic(res.Error)
}

Arguments

fields can be passed arguments for common tasks such as pagination or fetching a record by a given unique identifier.

Note: this package does not come with input validation builtin, but can be used with any validation package that implements the Args interface.

Example: resolve the users posts with pagination via arguments and validation using https://github.com/aacebo/owl

schema := gq.Object[User]{
	Name:        "User",
	Description: "...",
	Fields: gq.Fields{
		"id": gq.Field{
			Type: gq.String{},
		},
		"name": gq.Field{
			Type: gq.String{},
		},
		"email": gq.Field{
			Type: gq.String{},
		},
		"created_at": gq.Field{
			Type: gq.Date{},
		},
		"updated_at": gq.Field{
			Type: gq.Date{},
		},
		"posts": gq.Field{
			Type: gq.List{
				Type: gq.Object[Post]{
					Name: "Post",
					Fields: gq.Fields{
						"id": 	gq.Field{
							Type: gq.String{},
						},
						"text":	gq.Field{
							Type: gq.String{},
						},
					},
				},
			},
			Args: owl.Object().Fields(map[string]owl.Schema{
				"page": 	 owl.Int().Required(),
				"page_size": owl.Int().Required(),
			}).Required(),
			Description: "posts created by the user",
			DependsOn: []string{"id"}, // ensure `created_by_id` field resolves before this does.
			Resolver: func(params *gq.ResolveParams) gq.Result {
				args := params.Query.Args
				user := params.Parent.(User)
				posts := // fetch user posts somehow
				return gq.Result{Data: posts}
			},
		},
	},
}

res := schema.Do(&gq.DoParams{
	Query: "{id,name,email,posts{id,text}}",
	Value: User{
		ID: "1",
		Name: "test",
		Email: "[email protected]",
		CreatedAt: time.Now(),
		UpdatedAt: time.Now(),
	},
})

if res.Error != nil {
	panic(res.Error)
}