Giter Club home page Giter Club logo

graphiti's Introduction

Graphiti

Graphiti is a Swift library for building GraphQL schemas fast, safely and easily.

Swift License GitHub Actions Maintainability Coverage

Looking for help? Find resources from the community.

Getting Started

An overview of GraphQL in general is available in the README for the Specification for GraphQL. That overview describes a simple set of GraphQL examples that exist as tests in this repository. A good way to get started with this repository is to walk through that README and the corresponding tests in parallel.

Using Graphiti

Add Graphiti to your Package.swift

import PackageDescription

let package = Package(
    dependencies: [
        .package(url: "https://github.com/GraphQLSwift/Graphiti.git", .upToNextMinor(from: "0.20.1")),
    ]
)

Graphiti provides two important capabilities: building a type schema, and serving queries against that type schema.

Defining entities

First, we declare our regular Swift entities.

struct Message : Codable {
    let content: String
}

⭐️ One of the main design decisions behind Graphiti is not to polute your entities declarations. This way you can bring your entities to any other solution with ease.

Defining the context

Second step is to create your application's context. The context will be passed to all of your field resolver functions. This allows you to apply dependency injection to your API. This is the place where you can put code that talks to a database or another service.

struct Context {
    func message() -> Message {
        Message(content: "Hello, world!")
    }
}

⭐️ Notice again that this step doesn't require Graphiti. It's purely business logic.

Defining the GraphQL API resolver

Now that we have our entities and context we can create the GraphQL API resolver.

import Graphiti

struct Resolver {
    func message(context: Context, arguments: NoArguments) -> Message {
        context.message()
    }
}

Defining the GraphQL API schema

Now we can finally define the GraphQL API with its schema.

struct MessageAPI : API {
    let resolver: Resolver
    let schema: Schema<Resolver, Context>
}
        
let api = MessageAPI(
    resolver: Resolver()
    schema: try! Schema<Resolver, Context> {
        Type(Message.self) {
            Field("content", at: \.content)
        }

        Query {
            Field("message", at: Resolver.message)
        }
    }
)

Schemas may also be created in a modular way using SchemaBuilder:

SchemaBuilder API
let builder = SchemaBuilder(Resolver.self, Context.self)
builder.add(
    Type(Message.self) {
        Field("content", at: \.content)
    }
)
builder.query.add(
    Field("message", at: Resolver.message)
)
let schema = try builder.build()

let api = MessageAPI(
    resolver: Resolver()
    schema: schema
)
PartialSchema implementation
final class ChatSchema: PartialSchema<Resolver, Context> {
    @TypeDefinitions
    public override var types: Types {
        Type(Message.self) {
            Field("content", at: \.content)
        }        
    }

    @FieldDefinitions
    public override var query: Fields {
        Field("message", at: Resolver.message)
    }
}
let schema = try SchemaBuilder(Resolver.self, Context.self)
    .use(partials: [ChatSchema(), ...])
    .build()

let api = MessageAPI(
    resolver: Resolver()
    schema: schema
)
PartialSchema instance
let chatSchema = PartialSchema<Resolver, Context>(
    types:  {
        Type(Message.self) {
            Field("content", at: \.content)
        }        
    },
    query: {
        Field("message", at: Resolver.message)
    }
)
let schema = try SchemaBuilder(Resolver.self, Context.self)
    .use(partials: [chatSchema, ...])
    .build()

let api = MessageAPI(
    resolver: Resolver()
    schema: schema
)

⭐️ Notice that API allows dependency injection. You could pass mocks of resolver and context when testing, for example.

Querying

To query the schema we need to pass in a NIO EventLoopGroup to feed the execute function alongside the query itself.

import NIO

let group = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount)
defer {
    try? group.syncShutdownGracefully()
}

let result = try await api.execute(
    request: "{ message { content } }",
    context: Context(),
    on: group
)
print(result)

The output will be:

{"data":{"message":{"content":"Hello, world!"}}}

API.execute returns a GraphQLResult which adopts Encodable. You can use it with a JSONEncoder to send the response back to the client using JSON.

Async resolvers

Resolver functions can also be async:

struct Resolver {
    func message(context: Context, arguments: NoArguments) async -> Message {
        await someAsyncMethodToGetMessage()
    }
}

NIO resolvers

The resolver functions also support NIO-style concurrency. To do so, just add one more parameter with type EventLoopGroup to the resolver function and change the return type to EventLoopFuture<YouReturnType>. Don't forget to import NIO.

import NIO

struct Resolver {
    func message(context: Context, arguments: NoArguments, group: EventLoopGroup) -> EventLoopFuture<Message> {
        group.next().makeSucceededFuture(context.message())
    }
}

Subscription

This library supports GraphQL subscriptions, and supports them through the Swift Concurrency AsyncThrowingStream type. See the Usage Guide for details.

If you are unable to use Swift Concurrency, you must create a concrete subclass of the EventStream class that implements event streaming functionality. If you don't feel like creating a subclass yourself, you can use the GraphQLRxSwift repository to integrate RxSwift observables out-of-the-box. Or you can use that repository as a reference to connect a different stream library like ReactiveSwift, OpenCombine, or one that you've created yourself.

Additional Examples

For a progressive walkthrough, see the Usage Guide. The Star Wars API provides a fairly complete example.

Contributing

This repo uses SwiftFormat, and includes lint checks to enforce these formatting standards. To format your code, install swiftformat and run:

swiftformat .

License

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

graphiti's People

Contributors

adam-fowler avatar alexsteinerde avatar cagejsn avatar cshadek avatar cuva avatar cypherpoet avatar d-exclaimation avatar icanzilb avatar jaapwijnen avatar jseibert avatar kimdv avatar lgaches avatar maxdesiatov avatar needleinajaystack avatar noahemmet avatar paulofaria avatar samisuteria avatar sevki avatar sportlabsmike avatar williambailey avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

graphiti's Issues

Duplicate type registration

Is there any behaviour that relies on String(describing: type) in

// Sources/Graphiti/Definition/AnyType.swift

final class AnyType : Hashable {
	// ...
    func hash(into hasher: inout Hasher) {
        hasher.combine(String(describing: type))
    }
    // ...
}

It won't allow you to use nested types for your models like
ModelA.Response
ModelB.Response
And you will get an error

Duplicate type registration for GraphQLType "Response" while trying to register type Response

Using String(describing: type) will provide "ModelA.Response" string, .components(separatedBy: ".").joined() can remove the dot if needed. Should I submit a PR to support this stuff?

Are there any best-practices to deal with UUIDs?

Getting an error in the schema when creating type.

Fatal error: 'try!' expression unexpectedly raised an error: Cannot use type "Optional<UUID>" for field "id". Type does not map to a GraphQL type.

Non-optional UUID fails too

Fatal error: 'try!' expression unexpectedly raised an error: Cannot use type "UUID" for field "id". Type does not map to a GraphQL type.

I think of converting UUIDs to Strings somehow, but don't know yet how to handle it, any ideas appreciated :)

Graphiql

Is it possible to use GraphiQL with the created Graphiti scheme?

If yes, how? 😄

Type used for both Input and Output

I previously registered my type Address as a Type and it worked well to output data of this type.
Now I'd also like to be able to pass in an Address as an argument of a query and I simply can't wrap my head around a way to do it.
Without any other code change I get:

Fatal error: 'try!' expression unexpectedly raised an error: ⚠️ GraphQLError: Cannot use type "Optional<Address>" for field "myField". Mapped GraphQL type is not an input type.
- id: GraphQLError.GraphQLError
: file ../Graphiti/Schema/Query.swift, line 30

But if I then register it as a Input as well, I get a duplicated type error:

Fatal error: 'try!' expression unexpectedly raised an error: ⚠️ GraphQLError: Duplicate type registration: Address
- id: GraphQLError.GraphQLError
: file ../Graphiti/Schema/Input.swift, line 75

and finally I tried registering the type as only an Input but it still doesn't work:

Fatal error: 'try!' expression unexpectedly raised an error: ⚠️ GraphQLError: Resolved type "Address" is not a valid output type.
- id: GraphQLError.GraphQLError
: file ../Graphiti/Schema/Schema.swift, line 113

Is there a way to do that without duplicating the code?

Some types don't resolve anymore after updating to 1.2.1

After removing the Types construct as recommended in #84, some types don't resolve anymore.

So far I've been able to narrow it down to:

  1. Union types
  2. Connection types
  3. Types in an array
  4. Also types of fields on the type in an array no longer resolve and need to be included in the Types construct

If I keep the Types construct (which is deprecated) to include the types above and still remove all instances of TypeReference in the schema, it resolves.

Is there an example of a Graphiti schema using connections?

I noticed that @paulofaria added connections in an earlier commit. I was trying to use them in my code but have not succeeded in getting them working.

Here is what I have been trying. What am I missing here?

Inside the Schema Definition:

Type(User.self,
Field("id", at: \.id).description("The unique id of the user."),
Field("followersConnection", at: User.followers).description("The followers connection")
)

In another file:

class User: Codable, Identifiable {
var id: String? = UUID().uuidString

func followers(context: UserContext, arguments: ForwardPaginationArguments) -> EventLoopFuture<Connection<User>> {
        let arr = context.request.eventLoop.makeSucceededFuture([User()])
        return arr.connection(from: arguments)
    }
}

I get this error:

[ ERROR ] Cannot use type "Connection<User>" for field "followersConnection". Type does not map to a GraphQL type.

Thanks!

error: no such module 'Runtime'

Hi! My team is looking to use this package in our BFF and I was trying to get the docker image to build but I'm running into an issue where I see error: no such module 'Runtime' coming from /build/.build/checkouts/Graphiti/Sources/Graphiti/Field/Field/Field.swift:2:8:

I'm assuming I need to add some framework to my docker container but I'm not exactly sure which one? Any help would be much appreciated!

Thanks!
Nick

EventLoop generic parameter

This seems a little unusable with Vapor 3 as you get passed evenLoop in request which is not the multithreaded one, but different which is internal to Swift NIO. So I cannot really make Graphiti work with Vapor 3. Maybe I am missing a thing or two?

MultiThreadedEventLoopGroup seems to me like the only one thats public.

Variable is never used in operation for dynamic inner parameter

Getting Error:
{"errors":[{"message":"Variable "$userId" is never used in operation "listUserStudies".","locations":[{"line":2,"column":28}],"path":[]}]}

Query:
{
query listUsersStudies($userId: String!){
listUsersStudies(limit: 250,
filter: {
pk: {
matchPhrasePrefix: $userId
}
}){
items{
pk
sk
status
versionStr
versionStatus
}
}
}
}

Variable :
"{"userId":"d97ca8de9436"}

Its been 2 days I got stuck here, I tried many ways but nothing works.

Resolve Function not Found

Hello, I've tried a very simple example, not sure what I am doing wrong - I get the following error with the code below

{"errors":[{"message":"Could not find a resolve function.","locations":[{"line":2,"column":9}],"path":{"elements":[]}}]}


import Foundation
import NIO
import Graphiti

struct Workout: Codable {
    let id: String
    let duration: Int
}

final class WorkoutStore {

    lazy var workouts = [
        Workout(id: "1234", duration: 40)
    ]

    func getWorkouts() -> [Workout] {
        return workouts
    }

}

protocol SearchResult {}

extension Workout: SearchResult {}

extension Workout: FieldKeyProvider {
    typealias FieldKey = FieldKeys

    enum FieldKeys: String {
        case id
        case duration
    }
}

struct WorkoutsAPI: FieldKeyProvider {
    typealias FieldKey = FieldKeys

    enum FieldKeys: String {
        case id
        case workouts
    }

    func getWorkouts(store: WorkoutStore, arguments: NoArguments) -> [Workout] {
        store.getWorkouts()
    }

}


let workoutSchema = Schema<WorkoutsAPI, WorkoutStore> {

    Interface(Workout.self, fieldKeys: WorkoutFieldKeys.self) {
        Field(.id, at: \.id)
        Field(.duration, at: \.duration)
    }

    Query {
        Field(.workouts, at: WorkoutsAPI.getWorkouts)
    }

}


class Shred {
    init() {
        let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)

        defer {
            try? eventLoopGroup.syncShutdownGracefully()
        }

        let query = """
            query WorkoutsQuery {
                workouts {
                    id
                    duration
                }
            }
        """

        let API = WorkoutsAPI()
        // send this back to the client
        do {
            let result = try workoutSchema.execute(request: query, root:API, context: WorkoutStore(), eventLoopGroup: eventLoopGroup).wait()
            print(result)
        } catch {

        }

    }
}

Mutations should run in SERIES not parallel

I'm running Graphiti 0.26.0 and noticed that Mutations seem to be running in parallel when they should be running in series.

A simple example would be:

mutation Test {
    addLike(input: {id: 1}) {
       ....
    }
    removeLike(input: {id: 1} ) {
       ....
    }
    addLike2: addLike(input: {id: 1} ) {
       ....
    }
}

Ideally this should run the top fields in order, per the spec, but it doesn't and it seems to run them in parallel, leading to potential race conditions and unintended results.

If a type's name is overridden, then TypeReference behaves oddly.

If a type's name is overridden, then TypeReference does not seem to work.

Example (I want the schema to use the name Location instead of LocationObject):

Type(LocationObject.self, as: "Location",
                     Field("id", at: \.id),
                     Field("name", at: \.name),
),

Type(User.self,
                     Field("id", at: \.id),
                     Field("location", at: User.location, as: TypeReference<LocationObject>.self),
)

The following error is received when I try to load the schema:

{
  "errors": [
    {
      "message": "Unknown kind of type: LocationObject",
      "path": []
    }
  ]
}

Should I be doing something differently? Thanks!

PartialSchema Type extensions

I love the new SubSchema feature from @d-exclaimation!

I think it would be useful to have the ability to extended Types from one SubSchema in another SubSchema.

This would be a natural extension to the new declarative SubSchema feature and would allow you to break up a GraphQL type across multiple packages similar to Swift's extension feature.

Update to work with GraphQLSwift 0.4.0

I just started playing around with your other library, but was disappointed to find out that the latest version doesn't work with Graphiti. I tried forking the library and updating the Package.swift file, but there are a bunch of compile errors mostly due to changes in your Runtime dependency that I wasn't sure how to resolve. It would be great if these two could work together again.

Allow enum cases to be inferred if type conforms to `CaseIterable`

Currently you have to specify each case of an enum in the Schema type if you want to use it. This makes sense in case you want to only expose a specific range of cases to your public api.
But most of the times you want to expose all cases. So, a generalised function that infers all cases by requiring the protocol CaseIterable on the enum type.

An implementation could look like this.

extension Enum where EnumType: CaseIterable {
    public convenience init(
        _ type: EnumType.Type,
        name: String? = nil
    ) {
        self.init(type, name: name, EnumType.allCases.map({ Value($0) }))
    }
}

Do you think that this could also be useful for others? Is there any feedback on the idea?

Schema File

Hey,
It would be great to have the ability to provide a schema file to the server and start it with the file content.
Or is this already possible just not listed in the readme?
Thanks
Alex

GraphQLError extension to add error code

Question,
I'm looking for an easier way of parsing and handling errors on client.
I want to add an extension to the GraphQLError, So I can add an error code property.
Do you think it's possible?
I'm using Vapor so adding error headers to AbortError might also be an option, although I think extension would be much cleaner.

Not compiling in Xcode 11

Hello!

I just wanted to use Graphiti in my project, but the compiler throws a 'Segmentation fault: 11', when populating the 'Schema' with more than one 'Field' in a 'Type' or when adding a 'Query'.

While troubleshooting I forked and cloned Graphiti itself.
The compiler threw the same error, because of the Schema in the StarWarsTests.
As I removed all tests from the Graphiti project, the project could compile.

Has anyone experienced the same behaviours before?
Tried on two different machines with Xcode 11.2.1, 11.3 and Swift 5.1.2, 5.1.3

Regards,
Michael

Ambiguous use of field(name:type:description:deprecationReason:resolve:)

I'm trying to create a root query, "me", which takes no arguments, i.e.:

type Query {
    me(): User
}

I'm trying to construct it as follows:

func rootQuery<Root,Context>(schema: SchemaBuilder<Root,Context>) throws {
    try schema.query { query in
        try query.field(name: "me") { (_, argument: NoArguments, _, _) -> User in
            return getMe() // func getMe() -> User
        }
    }
}

I'm getting a compiler error that the field function is ambiguous. How can I resolve this?

Async Resolving

Hey. I want to resolve a query like the following

try schema.query { query in
        try query.field(name: "stations", type: Array<Station>.self) { x, y, z, m in
           networkcall({result in
              ???? //How to resolve from here
           }
        }
        
    }

Keep up the work

Function Builder type inferring is not working

Function builders provide a great usability especially for DSLs like Graphiti has build in.
But at the moment Function builders are still in a private-like state in the Swift development process. This can be seen on the underscore in front of the function name(@_functionBuilder).
It also makes some trouble in current Swift versions by not inferring types of the GraphQL schema builder classes.
I created a fork (https://github.com/alexsteinerde/Graphiti) and tried a temporary alternative for function builders: Arrays. It is not the perfect solution and when function builders will be working they should be used again but until then I think this is the best way to go at the moment.

Do you think this is an implementation that could be merged back into this repository to make it easier to discover by other and to make further development possible here?

Swift Compiler unable to type check long Schema expression

It seemed like the Schema result builder failed to compile if the schema is over 800 lines long. The error message thrown here is that the compiler was unable to type check the expression in a reasonable time.

Not sure how to resolve this, I had thought that the One-way constraints shipped in 5.1.1 kinda helped the problem, but apparently not.

Introspection error when defining an argument with default value.

Given this schema config:

let schema = try Graphiti.Schema<ResolverRoot, Request> {
    Scalar(UUID.self)

    // define graphql types
    
    Query {
        Field("profile", at: ResolverRoot.profile, as: [Profile].self) {
            Argument("input", at: \.input).defaultValue(.init(page: 0, limit: 10))
        }
    }
    Mutation {
        Field("createProfile", at: ResolverRoot.createProfile, as: Profile.self) {
            Argument("input", at: \.input)
        }
    }
}

When asked to be introspected it returns an error:

  • On Jetbrains Webstorm:

A valid schema could not be built using the introspection result. The endpoint may not follow the GraphQL Specification.
Error: internal error: should never happen: valueFromAst of '{"limit":10,"page":0}' failed because of 'Invalid Syntax : offending token '"limit"' at line 1 column 25'

  • On Insomnia

Failed to fetch schema: Syntax Error: Expected Name, found string "limit"

Removing the .defaultValue(...) fixes the problem but runs the impossibility of not having a default value on an optional argument in the query.

More context

The input defined is a generic struct:

struct Input<Payload: Codable>: Codable {
    let input: Payload
}

And the payload:

struct ProfileQueryInput: Codable {
    let page: Int
    var limit: Int = 10
}

When defining the GQL types, only ProfileQueryInput and not Input<ProfileQueryInput> is defined in the schema config.

Is there an HTTP Server reference/example that uses Graphiti?

This project is very interesting to me... but I wonder if there are any full graphql server implementations, aka: a swift server implementation that would be similar to Apollo Server (with authentication, HTTPS, etc) and compatible with existing Apollo GraphQL clients for Javascript and IOS (and other graphql clients).

I could definitely see building such a thing, and have been searching to see if anyone has at least a start/reference implementation on GitHub.

Would totally be interested in contributing to a project like that.

Latest version fails to compile

Steps to reproduce:

git clone https://github.com/GraphQLSwift/Graphiti
cd Graphiti
swift build

The build fails with:

.build/checkouts/swift-nio/Sources/NIO/CircularBuffer.swift:114:1: error: type 'CircularBuffer<Element>' does not conform to protocol 'MutableCollection'
extension CircularBuffer: Collection, MutableCollection {
^
.build/checkouts/swift-nio/Sources/NIO/CircularBuffer.swift:114:1: error: unavailable subscript 'subscript(_:)' was used to satisfy a requirement of protocol 'MutableCollection'
extension CircularBuffer: Collection, MutableCollection {
^

due to a breaking change in swift-collections.

Help: Cannot use array type

I have a User model and want to create a users resolve field, but I'm getting this:
Cannot use type "Array<User>" for field "users". Type does not map to a GraphQL type.

try builder.field(name: "users",
                  type: [User].self,
                  description: nil,
                  deprecationReason: nil,
                  resolve: { _ in return [] })

What's wrong? Should I use the GraphQLList type or there is a solution in Graphiti?

Question: What is the right way to access 1 to 1 connection (@OptionalChild)

I'm not really sure how to set optional child field on my schema, and access it as a connection.

I've got a User model, with Record as an optional child:

public final class User: Model {
    public static let schema = "users"
    
    @ID(key: .id)
    public var id: UUID?
    
    @OptionalField(key: "name")
    public var name: String?

    //MARK: Relations
    @OptionalChild(for: \.$user)
    public var record: Record?

    public init() { }

    public init(id: UUID? = nil,
                about: String? = nil) {
        self.id = id
        self.name = name
    }
}

The Record model:

public final class Record: Model {
    public static let schema = "records"
    
    @ID(key: .id)
    public var id: UUID?
    
    @Field(key: "type")
    public var type: Int
    
    //MARK: Relations
    @OptionalParent(key:"user_id")
    public var user: User?

    public init() { }

    public init(id: UUID? = nil,
                type: Int,
                userId: UUID? = nil) {
        self.id = id
        self.type = type
        self.$user.id = userId
    }
}

And I've defined my scheme like:

let schema = try! Schema<Resolver, Request> {
    Scalar(UUID.self).description("Unique ID Type")
    
    Type(User.self) {
        Field("id", at: \.id)
        Field("name", at: \.name)
        
        Field("record", at: \.$record, as: TypeReference<Record>?.self)
        //Field("record", at: \.$record, as: Record?.self) - also not working
    }
    
    Type(Record.self) {
        Field("id", at: \.id)
        Field("type", at: \.type)
        
        Field("user", with: \.$user)
    }
    
    Query {
        Field("user", at: Resolver.getUser) {
            Argument("id", at: \.id)
        }

        ...addUser
        ...addRecordToUser
    }
}

So I'm adding a user, and a record to this user ID, but when querying the user with its record field I get Expected value of type \"Record\" but got: Child<User, Record>(for: [user_id]).
What am I doing wrong here?

Subscription

Are there any way to create subscription in Graphiti/GraphQL? I have found method subscription() in SchemaBuilder but could not understand how to do actual data notification.

Improvements to SchemaBuilder and allowing sub schemas

I really like the recent changes regarding circular dependencies and Type Reference.

Something that may go hand in hand with this would be to have a schema also be able to take in sub schemas. Then you could define part of the schema in a different package and import it. Think similar to how SwiftUI works with ViewBuilders. I'm not sure how this would work with mutations and queries (since they effectively need to be combined at that level), but I think it would be useful.

Is this something that's been considered?

Can't validate request

Following Vapor's Validation API, I'm not really sure what is the right way to validate arguments in Graffiti.
I've made the arguments struct conform to Validatable but since I cannot call validate before it's being decode, I'm always getting 'field is required' error.

Graphiti crashes Linux Swift compiler

This is the Dockerfile I used to compile it

FROM swift:5.3 as build

WORKDIR /build
COPY ./Package.* ./
RUN swift package resolve

# Copy entire repo into container
COPY . .

RUN swift test --enable-test-discovery 

And these are the errors I am getting

#10 11.41 [235/246] Wrapping AST for Graphiti for debugging
#10 11.48 swift: /home/buildnode/jenkins/workspace/oss-swift-5.3-package-linux-ubuntu-18_04/swift/lib/AST/ASTScopeCreation.cpp:1276: swift::ast_scope::AnnotatedInsertionPoint swift::ast_scope::PatternEntryDeclScope::expandAScopeThatCreatesANewInsertionPoint(swift::ast_scope::ScopeCreator &): Assertion `(!getSourceManager().isBeforeInBuffer( patternEntry.getOriginalInit()->getStartLoc(), decl->getStartLoc())) && "Original inits are always after the '='" " Try compiling with '-disable-astscope-lookup'."' failed.
#10 11.48 Stack dump:
#10 11.48 0.	Program arguments: /usr/bin/swift -frontend -c /build/Tests/GraphitiTests/HelloWorldTests/HelloWorldTests.swift -primary-file /build/Tests/GraphitiTests/StarWarsAPI/StarWarsAPI.swift /build/Tests/GraphitiTests/StarWarsAPI/StarWarsContext.swift /build/Tests/GraphitiTests/StarWarsAPI/StarWarsEntities.swift /build/Tests/GraphitiTests/StarWarsAPI/StarWarsResolver.swift /build/Tests/GraphitiTests/StarWarsTests/StarWarsIntrospectionTests.swift /build/Tests/GraphitiTests/StarWarsTests/StarWarsQueryTests.swift -emit-module-path /build/.build/x86_64-unknown-linux-gnu/debug/GraphitiTests.build/StarWarsAPI/StarWarsAPI~partial.swiftmodule -emit-module-doc-path /build/.build/x86_64-unknown-linux-gnu/debug/GraphitiTests.build/StarWarsAPI/StarWarsAPI~partial.swiftdoc -emit-module-source-info-path /build/.build/x86_64-unknown-linux-gnu/debug/GraphitiTests.build/StarWarsAPI/StarWarsAPI~partial.swiftsourceinfo -emit-dependencies-path /build/.build/x86_64-unknown-linux-gnu/debug/GraphitiTests.build/StarWarsAPI/StarWarsAPI.d -emit-reference-dependencies-path /build/.build/x86_64-unknown-linux-gnu/debug/GraphitiTests.build/StarWarsAPI/StarWarsAPI.swiftdeps -target x86_64-unknown-linux-gnu -disable-objc-interop -I /build/.build/x86_64-unknown-linux-gnu/debug -I /build/.build/checkouts/swift-nio/Sources/CNIOSHA1/include -I /build/.build/checkouts/swift-nio/Sources/CNIOAtomics/include -I /build/.build/checkouts/swift-nio/Sources/CNIODarwin/include -I /build/.build/checkouts/swift-nio/Sources/CNIOLinux/include -enable-testing -g -module-cache-path /build/.build/x86_64-unknown-linux-gnu/debug/ModuleCache -swift-version 5 -Onone -D SWIFT_PACKAGE -D DEBUG -enable-anonymous-context-mangled-names -Xcc -fmodule-map-file=/build/.build/checkouts/CRuntime/Sources/CRuntime/module.modulemap -Xcc -fmodule-map-file=/build/.build/x86_64-unknown-linux-gnu/debug/CNIOSHA1.build/module.modulemap -Xcc -fmodule-map-file=/build/.build/x86_64-unknown-linux-gnu/debug/CNIOAtomics.build/module.modulemap -Xcc -fmodule-map-file=/build/.build/x86_64-unknown-linux-gnu/debug/CNIODarwin.build/module.modulemap -Xcc -fmodule-map-file=/build/.build/x86_64-unknown-linux-gnu/debug/CNIOLinux.build/module.modulemap -parse-as-library -module-name GraphitiTests -o /build/.build/x86_64-unknown-linux-gnu/debug/GraphitiTests.build/StarWarsAPI/StarWarsAPI.swift.o -index-store-path /build/.build/x86_64-unknown-linux-gnu/debug/index/store -index-system-modules 
#10 11.48 1.	Swift version 5.3.3 (swift-5.3.3-RELEASE)
#10 11.48 2.	While evaluating request TypeCheckSourceFileRequest(source_file "/build/Tests/GraphitiTests/StarWarsAPI/StarWarsAPI.swift")
#10 11.48 3.	While evaluating request TypeCheckFunctionBodyUntilRequest(GraphitiTests.(file).StarWarsAPI.init()@/build/Tests/GraphitiTests/StarWarsAPI/StarWarsAPI.swift:7:12, )
#10 11.48 4.	While evaluating request ExpandASTScopeRequest(NominalTypeBodyScope
#10 11.48 , (swift::ASTSourceFileScope*) 0x91332e8
#10 11.48 )
#10 11.48 5.	While evaluating request ExpandASTScopeRequest(PatternEntryDeclScope
#10 11.48 , (swift::ASTSourceFileScope*) 0x91332e8
#10 11.48 )
#10 11.48 6.	While evaluating request ExpandASTScopeRequest(PatternEntryInitializerScope
#10 11.48 , (swift::ASTSourceFileScope*) 0x91332e8
#10 11.48 )
#10 11.48 7.	While evaluating request ExpandASTScopeRequest(WholeClosureScope
#10 11.48 , (swift::ASTSourceFileScope*) 0x91332e8
#10 11.48 )
#10 11.48 8.	While evaluating request ExpandASTScopeRequest(ClosureBodyScope
#10 11.48 , (swift::ASTSourceFileScope*) 0x91332e8
#10 11.48 )
#10 11.48 9.	While evaluating request ExpandASTScopeRequest(BraceStmtScope
#10 11.48 , (swift::ASTSourceFileScope*) 0x91332e8
#10 11.48 )
#10 11.48 10.	While evaluating request ExpandASTScopeRequest(PatternEntryDeclScope
#10 11.48 , (swift::ASTSourceFileScope*) 0x91332e8
#10 11.48 )
#10 11.48 /usr/bin/swift[0x51fa1c4]
#10 11.48 /usr/bin/swift[0x51f7dbe]
#10 11.48 /usr/bin/swift[0x51fa49c]
#10 11.48 /lib/x86_64-linux-gnu/libpthread.so.0(+0x12980)[0x7fe8e1979980]
#10 11.48 /lib/x86_64-linux-gnu/libc.so.6(gsignal+0xc7)[0x7fe8dffe4fb7]
#10 11.48 /lib/x86_64-linux-gnu/libc.so.6(abort+0x141)[0x7fe8dffe6921]
#10 11.48 /lib/x86_64-linux-gnu/libc.so.6(+0x3048a)[0x7fe8dffd648a]
#10 11.48 /lib/x86_64-linux-gnu/libc.so.6(+0x30502)[0x7fe8dffd6502]
#10 11.48 /usr/bin/swift[0x1855a2a]
#10 11.48 /usr/bin/swift[0x185524f]
#10 11.48 /usr/bin/swift[0x185516c]
#10 11.48 /usr/bin/swift[0x1866866]
...

Is there a way to create parts of the schema in another file or function?

Is there a way to create parts of the schema in another file or function, similar to SwiftUI?

 init(resolver: Resolver) throws {
        ...
        self.schema = try Schema<RootAPI, UserContext> {
        
               OtherSchema()
               TypeDeclaredElseWhere()

        }
}

Where OtherSchema would be another schema or group of fields from another file or function.

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.