func ParseRequests(msg []byte) ([]*Request, error) {
	var req jmessages
	if err := req.parseJSON(msg); err != nil {
		return nil, err
	}
	var err error
	out := make([]*Request, len(req))
	for i, req := range req {
		if req.V != Version {
			err = ErrInvalidVersion
		}
		out[i] = &Request{
			id:     fixID(req.ID),
			method: req.M,
			params: req.P,
		}
	}
	return out, err
}
ParseRequests parses a single request or a batch of requests from JSON.
The result parameters are either nil or have concrete type json.RawMessage.

If any of the requests is missing or has an invalid JSON-RPC version, it
returns ErrInvalidVersion along with the parsed results. Otherwise, no
validation apart from basic structure is performed on the results.
package jrpc2
import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"strings"
	"github.com/creachadair/jrpc2/channel"
	"github.com/creachadair/jrpc2/code"
)
type Assigner interface {
	Assign(ctx context.Context, method string) Handler
	Names() []string
}
type Handler interface {
	Handle(context.Context, *Request) (interface{}, error)
}
type Request struct {
	id     json.RawMessage  
	method string           
	params json.RawMessage  
}
func (r *Request) IsNotification() bool { return r.id == nil }
func (r *Request) ID() string { return string(r.id) }
func (r *Request) Method() string { return r.method }
func (r *Request) HasParams() bool { return len(r.params) != 0 }
func (r *Request) UnmarshalParams(v interface{}) error {
	if len(r.params) == 0 {
		return nil
	}
	switch t := v.(type) {
	case *json.RawMessage:
		*t = json.RawMessage(string(r.params))  
		return nil
	case strictFielder:
		dec := json.NewDecoder(bytes.NewReader(r.params))
		dec.DisallowUnknownFields()
		if err := dec.Decode(v); err != nil {
			return Errorf(code.InvalidParams, "invalid parameters: %v", err.Error())
		}
		return nil
	}
	return json.Unmarshal(r.params, v)
}
func (r *Request) ParamString() string { return string(r.params) }
var ErrInvalidVersion = Errorf(code.InvalidRequest, "incorrect version marker")