graphql

package module
v1.11.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 4, 2024 License: MIT Imports: 35 Imported by: 52

README

Flamingo GraphQL

This module allows the usage of GraphQL services in your Flamingo project.

Example

The module contains a working example that you can try out yourself. See https://github.com/i-love-flamingo/graphql/tree/master/example

Use Graphql in your Flaming project

Create a new Module and bind a graphql.Service.

The service has both the Schema and Model-Mapping information.

It also makes sense to declare graphql.Module as a direct dependency from your model:

package todo

import (
	"flamingo.me/dingo"
	"flamingo.me/graphql"
	"flamingo.me/graphql/example/todo/domain"
	"flamingo.me/graphql/example/user"
	"github.com/99designs/gqlgen/codegen/config"
)

// Service for the todo graphql service
type service struct{}

// Schema getter for graphql
func (*service) Schema() []byte {
	// language=graphql
	return []byte(`
type Todo {
	id: ID!
	task: String!
	done: Boolean!
}
extend type User {
	todos: [Todo]
}
extend type Mutation {
	TodoAdd(user: ID!, task: String!): Todo
	TodoDone(todo: ID!, done: Boolean!): Todo
}
`)
}

// Types mapping between graphql and go
func (*service) Types(types *graphql.Types) {
	types.Map("Todo", domain.Todo{})
	config.Resolve("User", "todos", UserResolver{}, "Todos")
	config.Resolve("Mutation", "TodoAdd", MutationResolver{}, "TodoAdd")
	config.Resolve("Mutation", "TodoDone", MutationResolver{}, "TodoDone")
}

// Module struct for the todo module
type Module struct{}

// Configure registers the service graphql service
func (Module) Configure(injector *dingo.Injector) {
	injector.BindMulti(new(graphql.Service)).To(new(service))
}

// Depends marks dependency to the graphql Module
func (*Module) Depends() []dingo.Module {
	return []dingo.Module{
		new(graphql.Module),
	}
}

Setup Graphql in your Flamingo project

Add the graphql.Module to your projects modules.

Generate the local code by running go run main.go graphql. Better is to add the following lines to your project main file:

//go:generate rm -f graphql/generated.go
//go:generate go run -tags graphql main.go graphql

Then you can run go generate . instead of go run main.go graphql

After this the project specific graphql code is generated inside the folder graphql

You then also need to add the generated local Module to your main project file:


import (
    projectGraphql "yourpoject-namespace/graphql"
)

....
   new(projectGraphql.Module),
....

Now when you start your application you are able to use the graphql API and the graphql console. See the example folder for a complete example on how to use flamingo.me/graphql.

The next thing you need to do is to add Resolver to the file resolver.go:

Resolver and Modifier

Everything needs to be resolved, unless gqlgen can figure something out on its own.

Best practice here is to provide default resolvers in your code, which can be used via embedding. See example/user for an example UserQuery resolver.

Suggested Naming Conventions

We recommend to namespace your Types and Type extensions with the Project name. For Flamingo Core Framework GraphQL Schema we use the prefix Core_ and for Flamingo Commerce we use Commerce_

Config

You can enable LimitOperationAmountMiddleware to prevent batching attack by setting graphql.security.limitOperationAmount.enable to true.

graphql.security.limitOperationAmount.sameOperationLimit option can be used to set a limit for the same operations called in a single request.

graphql.security.limitOperationAmount.totalOperationLimit option can be used to set a limit for all the operations called in a single request.

Resources

Learn GraphQL: https://graphql.org/learn/

GraphQL Specification: https://graphql.github.io/graphql-spec/June2018/#sec-Schema

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrUnexpectedValue = errors.New("unexpected value")

Functions

func FlamingoResolver

func FlamingoResolver(_ context.Context) (*string, error)

FlamingoResolver always returns "flamingo" for default schemas.

func Generate

func Generate(services []Service, basePath string, schemaBasePath string) error

Generate runs the graphql generation for the defined services Usually you won't need this, and it's intended for infrastructure implementations.

func LimitOperationAmountMiddleware added in v1.11.0

func LimitOperationAmountMiddleware(
	cfg *struct {
		SameOperationLimit  int `inject:"config:graphql.security.limitOperationAmount.sameOperationLimit,optional"`
		TotalOperationLimit int `inject:"config:graphql.security.limitOperationAmount.totalOperationLimit,optional"`
	},
) func(ctx context.Context, next gql.OperationHandler) gql.ResponseHandler

func MarshalDate added in v1.2.0

func MarshalDate(t time.Time) graphql.Marshaler

MarshalDate marshals time.Time in form of YYYY-MM-DD

func MarshalFloat

func MarshalFloat(f big.Float) graphql.Marshaler

MarshalFloat for graphql Float scalars to be compatible with big.Float

func UnmarshalDate added in v1.2.0

func UnmarshalDate(v interface{}) (time.Time, error)

UnmarshalDate unmarshalls YYYY-MM-DD to time.Time

func UnmarshalFloat

func UnmarshalFloat(v interface{}) (big.Float, error)

UnmarshalFloat for graphql Float scalars to be compatible with big.Float

Types

type FlamingoQueryResolver

type FlamingoQueryResolver struct{}

FlamingoQueryResolver always resolves to the string "flamingo" for the default schemas.

func (*FlamingoQueryResolver) Flamingo

func (*FlamingoQueryResolver) Flamingo(ctx context.Context) (*string, error)

Flamingo field resolver

type Module

type Module struct {
	// contains filtered or unexported fields
}

Module defines the graphql entry point and binds the graphql command and routes

func (*Module) Configure

func (m *Module) Configure(injector *dingo.Injector)

Configure sets up dingo

func (*Module) CueConfig added in v1.5.0

func (m *Module) CueConfig() string

CueConfig for the module

func (*Module) Inject added in v1.11.0

func (m *Module) Inject(
	config *struct {
		EnableLimitQueryAmountMiddleware bool `inject:"config:graphql.security.limitOperationAmount.enable,optional"`
	},
)

Inject executable schema

type OpenCensusTracingExtension added in v1.10.0

type OpenCensusTracingExtension struct{}

func (*OpenCensusTracingExtension) ExtensionName added in v1.10.0

func (o *OpenCensusTracingExtension) ExtensionName() string

func (*OpenCensusTracingExtension) InterceptField added in v1.10.0

func (o *OpenCensusTracingExtension) InterceptField(ctx context.Context, next graphql.Resolver) (res interface{}, err error)

func (*OpenCensusTracingExtension) InterceptOperation added in v1.10.0

func (*OpenCensusTracingExtension) InterceptResponse added in v1.10.0

func (*OpenCensusTracingExtension) Validate added in v1.10.0

type Service

type Service interface {
	Schema() []byte
	Types(types *Types)
}

Service defines the interface for graphql services The Schema returns the GraphQL Schema definition The Types configure the GraphQL type mapping and resolution

type Types added in v1.1.0

type Types struct {
	// contains filtered or unexported fields
}

Types represent information on Object->Go type mappings and resolvers

func (*Types) Directive added in v1.9.0

func (tc *Types) Directive(graphqlDirective string, typ interface{}, method string)

Directive specifies a directive resolver for a graphql directive

func (*Types) GoField added in v1.1.0

func (tc *Types) GoField(graphqlType, graphqlField, goField string)

GoField sets a map to find the correct go field of an object

func (*Types) Map added in v1.1.0

func (tc *Types) Map(graphqlType string, goType interface{})

Map references a graphql type to a go type

func (*Types) Resolve added in v1.1.0

func (tc *Types) Resolve(graphqlType, graphqlField string, typ interface{}, method string)

Resolve sets a resolver on a graphqlType's graphqlField to a method of a go type

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL