func (c *Client) Noder(ctx context.Context, id int, opts ...NodeOption) (_ Noder, err error) {
	defer func() {
		if IsNotFound(err) {
			err = multierror.Append(err, entgql.ErrNodeNotFound(id))
		}
	}()
	table, err := c.newNodeOpts(opts).nodeType(ctx, id)
	if err != nil {
		return nil, err
	}
	return c.noder(ctx, table, id)
}
Noder returns a Node by its id. If the NodeType was not provided, it will
be derived from the id value according to the universal-id configuration.

c.Noder(ctx, id)
c.Noder(ctx, id, ent.WithNodeType(pet.Table))
package ent
import (
	"context"
	"encoding/json"
	"fmt"
	"sync"
	"sync/atomic"
	"entgo.io/contrib/entgql"
	"entgo.io/contrib/entgql/internal/todo/ent/category"
	"entgo.io/contrib/entgql/internal/todo/ent/todo"
	"entgo.io/ent/dialect"
	"entgo.io/ent/dialect/sql"
	"entgo.io/ent/dialect/sql/schema"
	"github.com/99designs/gqlgen/graphql"
	"github.com/hashicorp/go-multierror"
	"golang.org/x/sync/semaphore"
)
type Noder interface {
	Node(context.Context) (*Node, error)
}
type Node struct {
	ID     int      `json:"id,omitempty"`      
	Type   string   `json:"type,omitempty"`    
	Fields []*Field `json:"fields,omitempty"`  
	Edges  []*Edge  `json:"edges,omitempty"`   
}
type Field struct {
	Type  string `json:"type,omitempty"`   
	Name  string `json:"name,omitempty"`   
	Value string `json:"value,omitempty"`  
}
type Edge struct {
	Type string `json:"type,omitempty"`  
	Name string `json:"name,omitempty"`  
	IDs  []int  `json:"ids,omitempty"`   
}
func (c *Category) Node(ctx context.Context) (node *Node, err error) {
	node = &Node{
		ID:     c.ID,
		Type:   "Category",
		Fields: make([]*Field, 5),
		Edges:  make([]*Edge, 1),
	}
	var buf []byte
	if buf, err = json.Marshal(c.Text); err != nil {
		return nil, err
	}
	node.Fields[0] = &Field{
		Type:  "string",
		Name:  "text",
		Value: string(buf),
	}
	if buf, err = json.Marshal(c.Status); err != nil {
		return nil, err
	}
	node.Fields[1] = &Field{
		Type:  "category.Status",
		Name:  "status",
		Value: string(buf),
	}
	if buf, err = json.Marshal(c.Config); err != nil {
		return nil, err
	}
	node.Fields[2] = &Field{
		Type:  "*schematype.CategoryConfig",
		Name:  "config",
		Value: string(buf),
	}
	if buf, err = json.Marshal(c.Duration); err != nil {
		return nil, err
	}
	node.Fields[3] = &Field{
		Type:  "time.Duration",
		Name:  "duration",
		Value: string(buf),
	}
	if buf, err = json.Marshal(c.Count); err != nil {
		return nil, err
	}
	node.Fields[4] = &Field{
		Type:  "uint64",
		Name:  "count",
		Value: string(buf),
	}
	node.Edges[0] = &Edge{
		Type: "Todo",
		Name: "todos",
	}
	err = c.QueryTodos().
		Select(todo.FieldID).
		Scan(ctx, &node.Edges[0].IDs)
	if err != nil {
		return nil, err
	}
	return node, nil
}
func (t *Todo) Node(ctx context.Context) (node *Node, err error) {
	node = &Node{
		ID:     t.ID,
		Type:   "Todo",
		Fields: make([]*Field, 5),
		Edges:  make([]*Edge, 3),
	}
	var buf []byte
	if buf, err = json.Marshal(t.CreatedAt); err != nil {
		return nil, err
	}
	node.Fields[0] = &Field{
		Type:  "time.Time",
		Name:  "created_at",
		Value: string(buf),
	}
	if buf, err = json.Marshal(t.Status); err != nil {
		return nil, err
	}
	node.Fields[1] = &Field{
		Type:  "todo.Status",
		Name:  "status",
		Value: string(buf),
	}
	if buf, err = json.Marshal(t.Priority); err != nil {
		return nil, err
	}
	node.Fields[2] = &Field{
		Type:  "int",
		Name:  "priority",
		Value: string(buf),
	}
	if buf, err = json.Marshal(t.Text); err != nil {
		return nil, err
	}
	node.Fields[3] = &Field{
		Type:  "string",
		Name:  "text",
		Value: string(buf),
	}
	if buf, err = json.Marshal(t.Blob); err != nil {
		return nil, err
	}
	node.Fields[4] = &Field{
		Type:  "[]byte",
		Name:  "blob",
		Value: string(buf),
	}
	node.Edges[0] = &Edge{
		Type: "Todo",
		Name: "parent",
	}
	err = t.QueryParent().
		Select(todo.FieldID).
		Scan(ctx, &node.Edges[0].IDs)
	if err != nil {
		return nil, err
	}
	node.Edges[1] = &Edge{
		Type: "Todo",
		Name: "children",
	}
	err = t.QueryChildren().
		Select(todo.FieldID).
		Scan(ctx, &node.Edges[1].IDs)
	if err != nil {
		return nil, err
	}
	node.Edges[2] = &Edge{
		Type: "Category",
		Name: "category",
	}
	err = t.QueryCategory().
		Select(category.FieldID).
		Scan(ctx, &node.Edges[2].IDs)
	if err != nil {
		return nil, err
	}
	return node, nil
}
func (c *Client) Node(ctx context.Context, id int) (*Node, error) {
	n, err := c.Noder(ctx, id)
	if err != nil {
		return nil, err
	}
	return n.Node(ctx)
}
var errNodeInvalidID = &NotFoundError{"node"}
type NodeOption func(*nodeOptions)
func WithNodeType(f func(context.Context, int) (string, error)) NodeOption {
	return func(o *nodeOptions) {
		o.nodeType = f
	}
}
func WithFixedNodeType(t string) NodeOption {
	return WithNodeType(func(context.Context, int) (string, error) {
		return t, nil
	})
}
type nodeOptions struct {
	nodeType func(context.Context, int) (string, error)
}
func (c *Client) newNodeOpts(opts []NodeOption) *nodeOptions {
	nopts := &nodeOptions{}
	for _, opt := range opts {
		opt(nopts)
	}
	if nopts.nodeType == nil {
		nopts.nodeType = func(ctx context.Context, id int) (string, error) {
			return c.tables.nodeType(ctx, c.driver, id)
		}
	}
	return nopts
}