func NewServer(schema *Schema, query, mutation interface{}) (*Server, error) {
	if query == nil {
		return nil, xerrors.New("new server: query is required")
	}
	if mutation == nil && schema.mutation != nil {
		return nil, xerrors.New("new server: schema specified mutation type, but no mutation object given")
	}
	if mutation != nil && schema.mutation == nil {
		return nil, xerrors.New("new server: mutation object given, but no mutation type")
	}
	srv := &Server{
		schema: schema,
	}
	var err error
	srv.query, err = newOperation(schema, schema.query, query)
	if err != nil {
		return nil, xerrors.Errorf("new server: %w", err)
	}
	srv.mutation, err = newOperation(schema, schema.mutation, mutation)
	if err != nil {
		return nil, xerrors.Errorf("new server: %w", err)
	}
	return srv, nil
}
NewServer returns a new server that is backed by the given query object and
optional mutation object. These must either be objects that follow the rules
laid out in Field Resolution in the package documentation, or functions that
return such objects. Functions may have up to two parameters: an optional
context.Context followed by an optional *SelectionSet. The function may also
have an error return.

Top-level objects may also implement the OperationFinisher interface. See the
interface documentation for details.
package graphql
import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"reflect"
	"strconv"
	"go.opencensus.io/trace"
	"golang.org/x/xerrors"
	"zombiezen.com/go/graphql-server/internal/gqlang"
)
type Server struct {
	schema   *Schema
	query    operation
	mutation operation
}