Giter Club home page Giter Club logo

graphql-kit's Introduction

GraphQLKit

Language Vapor Version build

Easy setup of a GraphQL server with Vapor. It uses the GraphQL implementation of Graphiti.

Features

  • Arguments, operation name and query support
  • Normal access to the Request object as in normal Vapor request handlers
  • Accept JSON in the body of a POST request as the GraphQL query
  • POST and GET support
  •  Accept application/graphql content type requests
  • Downloadable schema file
  • Multi-Resolver support

Installation

import PackageDescription

let package = Package(
    dependencies: [
    .package(url: "https://github.com/alexsteinerde/graphql-kit.git", from: "2.0.0"),
    ],
    targets: [
    .target(name: "App", dependencies: ["GraphQLKit"]),
    ...
    ]
)

Getting Started

Define your schema

This package is setup to accept only Request objects as the context object for the schema. This gives the opportunity to access all functionality that Vapor provides, for example authentication, service management and database access. To see an example implementation please have a look at the vapor-graphql-template repository. This package only provides the needed functions to register an existing GraphQL schema on a Vapor application. To define your schema please refer to the Graphiti documentations. But by including this package some other helper functions are exposed:

Async Resolver

An EventLoopGroup parameter is no longer required for async resolvers as the Request context object already provides access to it's EventLoopGroup attribute eventLoop.

// Instead of adding an unnecessary parameter
func getAllTodos(store: Request, arguments: NoArguments, _: EventLoopGroup) throws -> EventLoopFuture<[Todo]> {
    Todo.query(on: store).all()
}

// You don't need to provide the eventLoopGroup parameter even when resolving a future.
func getAllTodos(store: Request, arguments: NoArguments) throws -> EventLoopFuture<[Todo]> {
    Todo.query(on: store).all()
}

Enums

It automatically resolves all cases of an enum if the type conforms to CaseIterable.

enum TodoState: String, CaseIterable {
    case open
    case done
    case forLater
}

Enum(TodoState.self),

Parent, Children and Siblings

Vapor has the functionality to fetch an objects parent, children or siblings automatically with @Parent, @Children and @Siblings types. To integrate this into GraphQL, GraphQLKit provides extensions to the Field type that lets you use the parent, children or siblings property as a keypath. Fetching of those related objects is then done automatically.

⚠️ Loading related objects in GraphQL has the N+1 problem. A solution would be to build a DataLoader package for Swift. But this hasn't been done yet.

final class User: Model {
    ...
    
    @Children(for: \.$user)
    var todos: [Todo]
    
    ...
}

final class Todo: Model {
    ...
    
    @Parent(key: "user_id")
    var user: User
    
    @Siblings(through: TodoTag.self, from: \.$todo, to: \.$tag)
    public var tags: [Tag]
    
    ...
}
// Schema types
Type(User.self) {
    Field("todos", with: \.$todos)
}

Type(Todo.self) {
    Field("user", with: \.$user)
    Field("tags", with: \.$tags)
}

Register the schema on the application

In your configure.swift file call the register(graphQLSchema: Schema<YourResolver, Request>, withResolver: YourResolver) on your Application instance. By default this registers the GET and POST endpoints at /graphql. But you can also pass the optional parameter at: and override the default value.

// Register the schema and it's resolver.
app.register(graphQLSchema: todoSchema, withResolver: TodoAPI())

License

This project is released under the MIT license. See LICENSE for details.

Contribution

You can contribute to this project by submitting a detailed issue or by forking this project and sending a pull request. Contributions of any kind are very welcome :)

graphql-kit's People

Contributors

alexsteinerde avatar maxdesiatov avatar maximkrouk avatar jaredh159 avatar portellaa avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.