A collection of Go packages for creating robust GraphQL APIs

Overview

api-fu GitHub Actions Go Report Card codecov Documentation Mentioned in Awesome Go

api-fu (noun)

  1. (informal) Mastery of APIs. 💊

Packages

  • The top level apifu package is an opinionated library that aims to make it as easy as possible to build APIs that conform to API-fu's ideals. See the examples directory for example usage.
  • The graphql package is an unopinionated library for building GraphQL APIs. If you agree with API-fu's ideals, you should use apifu instead, but if you want something lower level, the graphql package is still an excellent standalone GraphQL library. It fully supports all features of the June 2018 spec.
  • The graphqlws package is an unopinionated library for using the Apollo graphql-ws protocol. This allows you to serve your GraphQL API via WebSockets and provide subscription functionality.

Usage

API-fu builds GraphQL APIs with code. To begin, you need a config that at least defines a query field:

var fuCfg apifu.Config

fuCfg.AddQueryField("foo", &graphql.FieldDefinition{
    Type: graphql.StringType,
    Resolve: func(ctx *graphql.FieldContext) (interface{}, error) {
        return "bar", nil
    },
})

From there, you can build the API:

fu, err := apifu.NewAPI(&fuCfg)
if err != nil {
    panic(err)
}

And serve it:

fu.ServeGraphQL(w, r)

API-fu also has first-class support for common patterns such as nodes that are queryable using global ids. See the examples directory for more complete example code.

Features

✅ Supports all features of the latest GraphQL spec.

This includes null literals, error extensions, subscriptions, and directives.

🚅 Fast!

The graphql package is over twice as fast and several times more memory efficient than its inspiration (graphql-go/graphql).

pkg: github.com/ccbrown/api-fu/graphql/benchmarks
BenchmarkAPIFu
BenchmarkAPIFu-16        	     765	   1553517 ns/op	  890575 B/op	   22587 allocs/op
BenchmarkGraphQLGo
BenchmarkGraphQLGo-16    	     315	   3753681 ns/op	 3990220 B/op	   45952 allocs/op

⚡ïļ Supports efficient batching and concurrency without the use of goroutines.

The graphql package supports virtually any batching or concurrency pattern using low level primitives.

The apifu package provides high level ways to use them.

For example, you can define a resolver like this to do work in a goroutine:

fuCfg.AddQueryField("myField", &graphql.FieldDefinition{
    Type: graphql.IntType,
    Resolve: func(ctx *graphql.FieldContext) (interface{}, error) {
        return Go(ctx.Context, func() (interface{}, error) {
            return doSomethingComplex(), nil
        }), nil
    },
})

Or you can define a resolver like this to batch up queries, allowing you to minimize round trips to your database:

fuCfg.AddQueryField("myField", &graphql.FieldDefinition{
    Type: graphql.IntType,
    Resolve: Batch(func(ctx []*graphql.FieldContext) []graphql.ResolveResult {
        return resolveABunchOfTheseAtOnce(ctx)
    },
})

ðŸ’Ą Provides implementations for commonly used scalar types.

For example, the apifu package provides date-time and long (but JavaScript safe) integers.

ðŸ“Ą Implements handlers for HTTP and the Apollo graphql-ws protocol.

Once you've built your API, all you have to do is:

fu.ServeGraphQL(w, r)

Or:

fu.ServeGraphQLWS(w, r)

📖 Provides easy-to-use helpers for creating connections adhering to the Relay Cursor Connections Specification.

Just provide a name, cursor constructor, edge fields, and edge getter:

{
    "messagesConnection": apifu.TimeBasedConnection(&apifu.TimeBasedConnectionConfig{
        NamePrefix: "ChannelMessages",
        EdgeCursor: func(edge interface{}) apifu.TimeBasedCursor {
            message := edge.(*model.Message)
            return apifu.NewTimeBasedCursor(message.Time, string(message.Id))
        },
        EdgeFields: map[string]*graphql.FieldDefinition{
            "node": &graphql.FieldDefinition{
                Type: graphql.NewNonNullType(messageType),
                Resolve: func(ctx *graphql.FieldContext) (interface{}, error) {
                    return ctx.Object, nil
                },
            },
        },
        EdgeGetter: func(ctx *graphql.FieldContext, minTime time.Time, maxTime time.Time, limit int) (interface{}, error) {
            return ctxSession(ctx.Context).GetMessagesByChannelIdAndTimeRange(ctx.Object.(*model.Channel).Id, minTime, maxTime, limit)
        },
    }),
}

🛠 Can generate Apollo-like client-side type definitions and validate queries in source code.

The gql-client-gen tool can be used to generate types for use in client-side code as well as validate queries at compile-time. The generated types intelligently unmarshal inline fragments and fragment spreads based on __typename values.

See cmd/gql-client-gen for details.

API Design Guidelines

The following are guidelines that are recommended for all new GraphQL APIs. API-fu aims to make it easy to conform to these for robust and future-proof APIs:

  • All mutations should resolve to result types. No mutations should simply resolve to a node. For example, a createUser mutation should resolve to a CreateUserResult object with a user field rather than simply resolving to a User. This is necessary to keep mutations extensible. Likewise, subscriptions should not resolve directly to node types. For example, a subscription for messages in a chat room (chatRoomMessages) should resolve to a ChatRoomMessagesEvent type.
  • Nodes with 1-to-many relationships should make related nodes available via Relay Cursor Connections. Nodes should not have fields that simply resolve to lists of related nodes. Additionally, all connections must require a first or last argument that specifies the upper bound on the number of nodes returned by that connection. This makes it possible to determine an upper bound on the number of nodes returned by a query before that query begins execution, e.g. using rules similar to GitHub's.
  • Mutations that modify nodes should always include the updated version of that node in the result. This makes it easy for clients to maintain up-to-date state and tolerate eventual consistency (If a client updates a resource, then immediately requests it in a subsequent query, the server may provide a version of the resource that was cached before the update.).
  • Nodes should provide revision numbers. Each time a node is modified, the revision number must increment. This helps clients maintain up-to-date state and enables simultaneous change detection.
  • It should be easy for clients to query historical data and subscribe to real-time data without missing anything due to race conditions. The most transparent and fool-proof way to facilitate this is to make subscriptions immediately push a small history of events to clients as soon as they're started. The pushed history should generally only need to cover a few seconds' worth of events. If queries use eventual consistency, the pushed history should be at least as large as the query cache's TTL.

Versioning and Compatibility Guarantees

This library is not versioned. However, one guarantee is made: Any backwards-incompatible changes made will break your build at compile-time. If your application compiles after updating API-fu, you're good to go.

Issues
  • add graphql package tests

    add graphql package tests

    What it Does

    • Adds graphql package tests

    Steps to Test

    go test -v ./...

    opened by ccbrown 1
  • update websocket lib, fix race on close

    update websocket lib, fix race on close

    What it Does

    Steps to Test

    go test -v ./...

    opened by ccbrown 1
  • expose config's AdditionalTypes field

    expose config's AdditionalTypes field

    What it Does

    Useful for getting previously added types from the config.

    Steps to Test

    go test -v ./...

    opened by ccbrown 1
  • add mechanism for handling graphql-ws connection init parameters

    add mechanism for handling graphql-ws connection init parameters

    What it Does

    Add a mechanism for handling graphql-ws connection init parameters.

    Steps to Test

    go test -v ./...

    opened by ccbrown 1
  • allow json package for generated code to be overridden

    allow json package for generated code to be overridden

    What it Does

    Allow the JSON package for generated code to be overridden (e.g. with jsoniter).

    Steps to Test

    go test -v ./...

    opened by ccbrown 1
  • Optional execute hook

    Optional execute hook

    What it Does

    Adds the ability to wrap the actual graphql.Execute invocation for the purposes of logging or pre/post-processing. Also makes GetOperation public, which is useful e.g. to log the query's actual operation name.

    Steps to Test

    go test -v ./...

    opened by ccbrown 1
  • make async time-based connections work

    make async time-based connections work

    What it Does

    Steps to Test

    go test -v ./...

    opened by ccbrown 1
  • add benchmarks and readme section on speed

    add benchmarks and readme section on speed

    What it Does

    Adds benchmarks comparing API-Fu to GraphQL-Go.

    Steps to Test

    go test -v ./...

    opened by ccbrown 1
  • codecov yaml

    codecov yaml

    What it Does

    Adds CodeCov config with more reasonable thresholds so I don't get red X's for golint fixes that "reduce coverage by 0.03%" with no real code changes.

    Steps to Test

    go test -v ./...

    opened by ccbrown 1
  • gql-client-gen fix for frags in frags

    gql-client-gen fix for frags in frags

    What it Does

    Fixes json.Unmarshaler not being implemented for nested fragment type definitions.

    Steps to Test

    go test -v ./...

    opened by ccbrown 1
  • Add this to golang-graphql-benchmark?

    Add this to golang-graphql-benchmark?

    Add this to https://github.com/appleboy/golang-graphql-benchmark/?

    opened by frederikhors 0
  • Congratulations and questions.

    Congratulations and questions.

    I just found out about your project. Incredibly gorgeous!

    You have summarized in your Readme everything I have ever thought about GraphQL since I discovered it.

    Two things:

    1. What do you think about creating a real-project demo repository that is not the usual VERY SIMPLE todo but something more complex? E.g. relations between entities, dataloaders; maybe without considering authentication because everyone has their own systems and this is not the task of this package.

    2. What do you think about gqlgen? The very convenient thing is the generation of the Go code starting from the GraphQL schema. The slowness of writing the code by hand is scary, what do you think about automatically generating the code?

    Thanks again and again congratulations!

    opened by frederikhors 2
Owner
Chris
Chris
graphql parser + utilities

graphql utilities for dealing with GraphQL queries in Go. This package focuses on actually creating GraphQL servers and expects you to describe your s

Travis Cline 54 Nov 26, 2021
GraphQL server with a focus on ease of use

graphql-go The goal of this project is to provide full support of the GraphQL draft specification with a set of idiomatic, easy to use Go packages. Wh

null 4k Jan 15, 2022
An implementation of GraphQL for Go / Golang

graphql An implementation of GraphQL in Go. Follows the official reference implementation graphql-js. Supports: queries, mutations & subscriptions. Do

null 8.2k Jan 15, 2022
Convert Golang Struct To GraphQL Object On The Fly

Straf Convert Golang Struct To GraphQL Object On The Fly Easily Create GraphQL Schemas Example Converting struct to GraphQL Object type UserExtra stru

Roshan Mehta 32 Oct 27, 2021
GraphQL server with a focus on ease of use

graphql-go The goal of this project is to provide full support of the GraphQL draft specification with a set of idiomatic, easy to use Go packages. Wh

null 4k Jan 15, 2022
GQLEngine is the best productive solution for implementing a GraphQL server 🚀

GQLEngine is the best productive solution for implementing a graphql server for highest formance examples starwars: https://github.com/gqlengine/starw

null 85 Dec 29, 2021
⚡ïļ A Go framework for rapidly building powerful graphql services

Thunder is a Go framework for rapidly building powerful graphql servers. Thunder has support for schemas automatically generated from Go types, live q

null 1.4k Jan 17, 2022
go generate based graphql server library

gqlgen What is gqlgen? gqlgen is a Go library for building GraphQL servers without any fuss. gqlgen is based on a Schema first approach — You get to D

99designs 7k Jan 17, 2022
gqlanalysis makes easy to develop static analysis tools for GraphQL in Go.

gqlanalysis gqlanalysis defines the interface between a modular static analysis for GraphQL in Go. gqlanalysis is inspired by go/analysis. gqlanalysis

null 31 Nov 13, 2021
Tools to write high performance GraphQL applications using Go/Golang.

graphql-go-tools Sponsors WunderGraph Are you looking for a GraphQL e2e data fetching solution? Supports frameworks like NextJS, type safety with gene

Jens Neuse 265 Jan 23, 2022
Go monolith with embedded microservices including GRPC,REST,GraphQL and The Clean Architecture.

GoArcc - Go monolith with embedded microservices including GRPC,REST, graphQL and The Clean Architecture. Description When you start writing a Go proj

Deqode 76 Jan 13, 2022
GraphQL implementation for click house in Go.

clickhouse-graphql-go GraphQL implementation for clickhouse in Go. This package stores real time streaming websocket data in clickhouse and uses Graph

Rakesh R 6 Jan 14, 2022
GraphQL parser comparison in different languages

graphql-parser-bench Parsing a schema or document can be a critical part of the application, especially if you have to care about latency. This is the

Dustin Deus 20 Oct 27, 2021
A simple Go, GraphQL, and PostgreSQL starter template

Simple Go/GraphQL/PostgreSQL template Purpose Have a good starting point for any project that needs a graphql, go, and postgres backend. It's a very l

Chris 0 Jan 8, 2022
A GraphQL complete example using Golang And PostgreSQL

GraphQL with Golang A GraphQL complete example using Golang & PostgreSQL Installation Install the dependencies go get github.com/graphql-go/graphql go

Santo Shakil 1 Jan 7, 2022
This app is an attempt towards using go lang with graphql data fetch in react front end.

go_movies _A React js + GraphQL supported with backend in GoLang. This app is an attempt towards using go lang with graphql data fetch in react front

Abhijit Mukherjee 0 Dec 7, 2021
proof-of-concept minimal GraphQL service for LTV

LTV GraphQL Proof-of-Concept This is a barebones proof-of-concept of a possible GraphQL implementation that interacts with Core. It includes a few ver

Nick Kelley 1 Jan 4, 2022
Learn GraphQL with THE [email protected] SHINY COLORS.

faaaar Learn GraphQL with THE [email protected] SHINY COLORS. Getting Started The following is a simple example which get information about 20-year-old idols

tokizo 0 Jan 16, 2022
GraphJin - Build APIs in 5 minutes with GraphQL. An instant GraphQL to SQL compiler.

GraphJin - Build APIs in 5 minutes GraphJin gives you a high performance GraphQL API without you having to write any code. GraphQL is automagically co

Vikram Rangnekar 1.7k Jan 12, 2022
GraphJin - Build APIs in 5 minutes with GraphQL. An instant GraphQL to SQL compiler.

GraphJin - Build APIs in 5 minutes GraphJin gives you a high performance GraphQL API without you having to write any code. GraphQL is automagically co

Vikram Rangnekar 1.7k Jan 18, 2022
GraphJin - Build APIs in 5 minutes with GraphQL. An instant GraphQL to SQL compiler.

GraphJin gives you a high performance GraphQL API without you having to write any code. GraphQL is automagically compiled into an efficient SQL query. Use it either as a library or a standalone service.

Vikram Rangnekar 1.7k Jan 22, 2022
Gosfdc module - a collection of packages containing the data structures from the various Salesforce APIs and Tools

Gosfdc module - a collection of packages containing the data structures from the various Salesforce APIs and Tools

Rodolphe Blancho 0 Jan 21, 2022
ðŸ’ĻA well crafted go packages that help you build robust, reliable, maintainable microservices.

Hippo A Microservices Toolkit. Hippo is a collection of well crafted go packages that help you build robust, reliable, maintainable microservices. It

Ahmed 139 Dec 13, 2021
A code generator that turns plain old Go services into RPC-enabled (micro)services with robust HTTP APIs.

Frodo Frodo is a code generator and runtime library that helps you write RPC-enabled (micro) services and APIs. It parses the interfaces/structs/comme

Rob Signorelli 14 Jan 12, 2022
A code generator that turns plain old Go services into RPC-enabled (micro)services with robust HTTP APIs.

Frodo is a code generator and runtime library that helps you write RPC-enabled (micro) services and APIs.

Monadic 14 Jan 12, 2022
A collection of packages to augment the go testing package and support common patterns.

gotest.tools A collection of packages to augment testing and support common patterns. Usage With Go modules enabled (go1.11+) $ go get gotest.tools/v3

null 273 Jan 12, 2022
A collection of authentication Go packages related to OIDC, JWKs and Distributed Claims.

cap (collection of authentication packages) provides a collection of related packages which enable support for OIDC, JWT Verification and Distributed Claims.

HashiCorp 313 Jan 13, 2022
gophertunnel is composed of several packages that may be of use for creating Minecraft related tools

gophertunnel is composed of several packages that may be of use for creating Minecraft related tools. A brief overview of all packages may be found here.

Sandertv 236 Jan 17, 2022
GoPrisma - A Go wrapper for prisma to turn databases into GraphQL APIs using Go.

GoPrisma - a Go wrapper for the Prisma Engines What's this? Introspect a database and use it as a GraphQL API using Go. Supported Databases: SQLite Po

Jens Neuse 54 Dec 29, 2021