Documentation ¶
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewHandler ¶
func NewHandler(h MessageHandler, opts ...ServerOption) http.Handler
NewHandler configures an http.Handler, which will upgrade incoming connections to WebSocket and serve the "graphql-ws" subprotocol.
Types ¶
type Client ¶
type Client interface { // Query provides an RPC like API for performing GraphQL queries. Query(context.Context, *Request) (*Response, error) }
Client provides high-level API for making GraphQL requests over WebSocket.
func NewClient ¶
NewClient takes a connection and initializes a client over it.
Example (Concurrent) ¶
conn, err := Dial(context.TODO(), "ws://example.com") if err != nil { // Make sure to handle the error return } defer conn.Close() // Performing queries is completely concurrent safe. client := NewClient(conn) respCh := make(chan *Response) go func() { resp, err := client.Query(context.TODO(), &Request{Query: "{ hello { world } }"}) if err != nil { // Remember, always handle errors return } respCh <- resp }() go func() { resp, err := client.Query(context.TODO(), &Request{Query: "{ hello { world } }"}) if err != nil { // Remember, always handle errors return } respCh <- resp }() for resp := range respCh { // Always check resp.Errors fmt.Println(resp) }
Output:
Example (Query) ¶
conn, err := Dial(context.TODO(), "ws://example.com") if err != nil { // Make sure to handle the error return } defer conn.Close() client := NewClient(conn) resp, err := client.Query(context.TODO(), &Request{Query: "{ hello { world } }"}) if err != nil { // Remember, always handle errors return } // Always check resp.Errors var exampleResp struct { Hello struct { World string `json:"world"` } `json:"hello"` } err = json.Unmarshal(resp.Data, &exampleResp) if err != nil { return } // Now, exampleResp.Hello.World would be your query result.
Output:
type CompressionMode ¶
type CompressionMode websocket.CompressionMode
CompressionMode represents the modes available to the deflate extension. See https://tools.ietf.org/html/rfc7692
A compatibility layer is implemented for the older deflate-frame extension used by safari. See https://tools.ietf.org/html/draft-tyoshino-hybi-websocket-perframe-deflate-06 It will work the same in every way except that we cannot signal to the peer we want to use no context takeover on our side, we can only signal that they should. It is however currently disabled due to Safari bugs. See https://github.com/nhooyr/websocket/issues/218
const ( // CompressionNoContextTakeover grabs a new flate.Reader and flate.Writer as needed // for every message. This applies to both server and client side. // // This means less efficient compression as the sliding window from previous messages // will not be used but the memory overhead will be lower if the connections // are long lived and seldom used. // // The message will only be compressed if greater than 512 bytes. // CompressionNoContextTakeover CompressionMode = iota // CompressionContextTakeover uses a flate.Reader and flate.Writer per connection. // This enables reusing the sliding window from previous messages. // As most WebSocket protocols are repetitive, this can be very efficient. // It carries an overhead of 8 kB for every connection compared to CompressionNoContextTakeover. // // If the peer negotiates NoContextTakeover on the client or server side, it will be // used instead as this is required by the RFC. // CompressionContextTakeover // CompressionDisabled disables the deflate extension. // // Use this if you are using a predominantly binary protocol with very // little duplication in between messages or CPU and memory are more // important than bandwidth. // CompressionDisabled )
type Conn ¶
type Conn struct {
// contains filtered or unexported fields
}
Conn is a client connection that should be closed by the client.
func Dial ¶
Dial creates a connection to the given endpoint. By default, it's a non-blocking dial (the function won't wait for connections to be established, and connecting happens in the background).
Example ¶
conn, err := Dial(context.TODO(), "ws://example.com") if err != nil { // Make sure to handle the error return } defer conn.Close() // Create a single client with the connection. // There is no need to create multiple connections or clients // because it will all be managed for you.
Output:
type ConnOption ¶
type ConnOption interface { DialOption ServerOption }
ConnOption represents a configuration that applies symmetrically on both sides, client and server.
func WithCompression ¶
func WithCompression(mode CompressionMode, threshold int) ConnOption
WithCompression configures compression over the WebSocket. By default, compression is disabled and for now is considered an experimental feature.
type DialOption ¶
type DialOption interface {
SetDial(*dialOpts)
}
DialOption configures how we set up the connection.
func WithHTTPClient ¶
func WithHTTPClient(client *http.Client) DialOption
WithHTTPClient provides an http.Client to override the default one used.
func WithHeaders ¶
func WithHeaders(headers http.Header) DialOption
WithHeaders adds custom headers to every dial HTTP request.
type ErrUnexpectedMessage ¶
type ErrUnexpectedMessage struct { // Expected was the expected message type. Expected string // Received was the received message type. Received string }
ErrUnexpectedMessage represents a unexpected message type.
func (ErrUnexpectedMessage) Error ¶
func (e ErrUnexpectedMessage) Error() string
Error implements the error interface.
type MessageHandler ¶
MessageHandler is a user provided function for handling incoming GraphQL queries. All other "GraphQL over Websocket" protocol messages are automatically handled internally. All resolvers errors should be included in *Response and any validation error should be returned as error.
type Request ¶
type Request struct { Query string `json:"query"` Variables map[string]interface{} `json:"variables"` OperationName string `json:"operationName"` }
Request represents a payload sent from the client.
type Response ¶
type Response struct { Data json.RawMessage `json:"data"` Errors []json.RawMessage `json:"errors"` }
Response represents a payload returned from the server. It supports lazy decoding by leaving the inner data for the user to decode.
type ServerError ¶
type ServerError struct {
Msg string `json:"msg"`
}
ServerError represents a payload which is sent by the server if it encounters a non-GraphQL resolver error.
func (*ServerError) Error ¶
func (e *ServerError) Error() string
Error implements the error interface.
type ServerOption ¶
type ServerOption interface {
SetServer(*options)
}
ServerOption allows the user to configure the handler.
func WithOrigins ¶
func WithOrigins(origins ...string) ServerOption
WithOrigins lists the host patterns for authorized origins. The request host is always authorized. Use this to allow cross origin WebSockets.