Implementation of the GraphQL over WebSocket protocol in Go.
Note: We're looking for a new maintainer for
graphqlws. Please reach out via [email protected] if you're interested.
Implementation of the GraphQL over WebSocket protocol in Go. Brought to you by Functional Foundry.
sh go get github.com/sirupsen/logrus go get github.com/x-cray/logrus-prefixed-formatter go get github.com/google/uuid go get github.com/gorilla/websocket go get github.com/graphql-go/graphql
sh mkdir -p "$GOPATH/src/github.com/functionalfoundry" cd "$GOPATH/src/github.com/functionalfoundry" git clone https://github.com/functionalfoundry/graphqlws
sh cd graphqlws go test
sh go run graphqlws/examples/server
package mainimport ( "net/http"
"github.com/functionalfoundry/graphqlws" "github.com/graphql-go/graphql"
)
func main() { // Create a GraphQL schema schema, err := graphql.NewSchema(...)
// Create a subscription manager subscriptionManager := graphqlws.NewSubscriptionManager(&schema) // Create a WebSocket/HTTP handler graphqlwsHandler := graphqlws.NewHandler(graphqlws.HandlerConfig{ // Wire up the GraphqL WebSocket handler with the subscription manager SubscriptionManager: subscriptionManager, // Optional: Add a hook to resolve auth tokens into users that are // then stored on the GraphQL WS connections Authenticate: func(authToken string) (interface{}, error) { // This is just a dumb example return "Joe", nil }, }) // The handler integrates seamlessly with existing HTTP servers http.Handle("/subscriptions", graphqlwsHandler) http.ListenAndServe(":8080", nil)
}
// This assumes you have access to the above subscription manager subscriptions := subscriptionManager.Subscriptions()for conn, _ := range subscriptions { // Things you have access to here: conn.ID() // The connection ID conn.User() // The user returned from the Authenticate function
for _, subscription := range subscriptions[conn] { // Things you have access to here: subscription.ID // The subscription ID (unique per conn) subscription.OperationName // The name of the operation subscription.Query // The subscription query/queries string subscription.Variables // The subscription variables subscription.Document // The GraphQL AST for the subscription subscription.Fields // The names of top-level queries subscription.Connection // The GraphQL WS connection // Prepare an execution context for running the query ctx := context.Context() // Re-execute the subscription query params := graphql.Params{ Schema: schema, // The GraphQL schema RequestString: subscription.Query, VariableValues: subscription.Variables, OperationName: subscription.OperationName, Context: ctx, } result := graphql.Do(params) // Send query results back to the subscriber at any point data := graphqlws.DataMessagePayload{ // Data can be anything (interface{}) Data: result.Data, // Errors is optional ([]error) Errors: graphqlws.ErrorsFromGraphQLErrors(result.Errors), } subscription.SendData(&data) }
}
graphqlwsuses logrus for logging. In the future we might remove those logs entirely to leave logging entirely to developers using
graphqlws. Given the current solution, you can control the logging level of
graphqlwsby setting it through
logrus:
import ( log "github.com/sirupsen/logrus" )...
log.SetLevel(log.WarnLevel)
Copyright © 2017-2019 Functional Foundry, LLC.
Licensed under the MIT License.