Repository files navigation

Graphiti

PlatformsVersionsLicenseGitHub Actions

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

To expose your schema through HTTP, check out graphql-vapor or graphql-hummingbird, and to generate Swift code from GraphQL SDL files, use graphql-generator instead.

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
letpackage=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.

structMessage:Codable{letcontent: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.

structContext{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
structResolver{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.

structMessageAPI:API{letresolver:Resolverletschema:Schema<Resolver,Context>}letapi=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
letbuilder=SchemaBuilder(Resolver.self,Context.self)
builder.add(Type(Message.self){Field("content", at: \.content)})
builder.query.add(Field("message", at:Resolver.message))letschema=try builder.build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)
PartialSchema implementation
finalclassChatSchema:PartialSchema<Resolver,Context>{@TypeDefinitionspublicoverridevartypes:Types{Type(Message.self){Field("content", at: \.content)}}@FieldDefinitionspublicoverridevarquery:Fields{Field("message", at:Resolver.message)}}letschema=trySchemaBuilder(Resolver.self,Context.self).use(partials:[ChatSchema(),...]).build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)
PartialSchema instance
letchatSchema=PartialSchema<Resolver,Context>(
types:{Type(Message.self){Field("content", at: \.content)}},
query:{Field("message", at:Resolver.message)})letschema=trySchemaBuilder(Resolver.self,Context.self).use(partials:[chatSchema,...]).build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)

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

Querying

letresult=tryawait api.execute(
request:"{ message { content } }",
context:Context())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:

structResolver{func message(context:Context, arguments:NoArguments)async->Message{awaitsomeAsyncMethodToGetMessage()}}

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.

Support

This package supports Swift versions in alignment with Swift NIO.

Contributing

This repo uses the standard swift format, and includes lint checks to enforce these formatting standards. To format your code, run:

swift format --parallel --in-place --recursive ./

License

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

About

The Swift GraphQL Schema builder for macOS and Linux

Topics

Resources

Stars

562 stars

Watchers

15 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Graphiti

PlatformsVersionsLicenseGitHub Actions

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

To expose your schema through HTTP, check out graphql-vapor or graphql-hummingbird, and to generate Swift code from GraphQL SDL files, use graphql-generator instead.

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
letpackage=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.

structMessage:Codable{letcontent: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.

structContext{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
structResolver{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.

structMessageAPI:API{letresolver:Resolverletschema:Schema<Resolver,Context>}letapi=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
letbuilder=SchemaBuilder(Resolver.self,Context.self)
builder.add(Type(Message.self){Field("content", at: \.content)})
builder.query.add(Field("message", at:Resolver.message))letschema=try builder.build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)
PartialSchema implementation
finalclassChatSchema:PartialSchema<Resolver,Context>{@TypeDefinitionspublicoverridevartypes:Types{Type(Message.self){Field("content", at: \.content)}}@FieldDefinitionspublicoverridevarquery:Fields{Field("message", at:Resolver.message)}}letschema=trySchemaBuilder(Resolver.self,Context.self).use(partials:[ChatSchema(),...]).build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)
PartialSchema instance
letchatSchema=PartialSchema<Resolver,Context>(
types:{Type(Message.self){Field("content", at: \.content)}},
query:{Field("message", at:Resolver.message)})letschema=trySchemaBuilder(Resolver.self,Context.self).use(partials:[chatSchema,...]).build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)

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

Querying

letresult=tryawait api.execute(
request:"{ message { content } }",
context:Context())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:

structResolver{func message(context:Context, arguments:NoArguments)async->Message{awaitsomeAsyncMethodToGetMessage()}}

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.

Support

This package supports Swift versions in alignment with Swift NIO.

Contributing

This repo uses the standard swift format, and includes lint checks to enforce these formatting standards. To format your code, run:

swift format --parallel --in-place --recursive ./

License

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

About

The Swift GraphQL Schema builder for macOS and Linux

Topics

Resources

Stars

562 stars

Watchers

15 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Graphiti

PlatformsVersionsLicenseGitHub Actions

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

To expose your schema through HTTP, check out graphql-vapor or graphql-hummingbird, and to generate Swift code from GraphQL SDL files, use graphql-generator instead.

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
letpackage=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.

structMessage:Codable{letcontent: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.

structContext{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
structResolver{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.

structMessageAPI:API{letresolver:Resolverletschema:Schema<Resolver,Context>}letapi=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
letbuilder=SchemaBuilder(Resolver.self,Context.self)
builder.add(Type(Message.self){Field("content", at: \.content)})
builder.query.add(Field("message", at:Resolver.message))letschema=try builder.build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)
PartialSchema implementation
finalclassChatSchema:PartialSchema<Resolver,Context>{@TypeDefinitionspublicoverridevartypes:Types{Type(Message.self){Field("content", at: \.content)}}@FieldDefinitionspublicoverridevarquery:Fields{Field("message", at:Resolver.message)}}letschema=trySchemaBuilder(Resolver.self,Context.self).use(partials:[ChatSchema(),...]).build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)
PartialSchema instance
letchatSchema=PartialSchema<Resolver,Context>(
types:{Type(Message.self){Field("content", at: \.content)}},
query:{Field("message", at:Resolver.message)})letschema=trySchemaBuilder(Resolver.self,Context.self).use(partials:[chatSchema,...]).build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)

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

Querying

letresult=tryawait api.execute(
request:"{ message { content } }",
context:Context())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:

structResolver{func message(context:Context, arguments:NoArguments)async->Message{awaitsomeAsyncMethodToGetMessage()}}

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.

Support

This package supports Swift versions in alignment with Swift NIO.

Contributing

This repo uses the standard swift format, and includes lint checks to enforce these formatting standards. To format your code, run:

swift format --parallel --in-place --recursive ./

License

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

About

The Swift GraphQL Schema builder for macOS and Linux

Topics

Resources

Stars

562 stars

Watchers

15 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Graphiti

PlatformsVersionsLicenseGitHub Actions

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

To expose your schema through HTTP, check out graphql-vapor or graphql-hummingbird, and to generate Swift code from GraphQL SDL files, use graphql-generator instead.

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
letpackage=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.

structMessage:Codable{letcontent: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.

structContext{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
structResolver{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.

structMessageAPI:API{letresolver:Resolverletschema:Schema<Resolver,Context>}letapi=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
letbuilder=SchemaBuilder(Resolver.self,Context.self)
builder.add(Type(Message.self){Field("content", at: \.content)})
builder.query.add(Field("message", at:Resolver.message))letschema=try builder.build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)
PartialSchema implementation
finalclassChatSchema:PartialSchema<Resolver,Context>{@TypeDefinitionspublicoverridevartypes:Types{Type(Message.self){Field("content", at: \.content)}}@FieldDefinitionspublicoverridevarquery:Fields{Field("message", at:Resolver.message)}}letschema=trySchemaBuilder(Resolver.self,Context.self).use(partials:[ChatSchema(),...]).build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)
PartialSchema instance
letchatSchema=PartialSchema<Resolver,Context>(
types:{Type(Message.self){Field("content", at: \.content)}},
query:{Field("message", at:Resolver.message)})letschema=trySchemaBuilder(Resolver.self,Context.self).use(partials:[chatSchema,...]).build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)

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

Querying

letresult=tryawait api.execute(
request:"{ message { content } }",
context:Context())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:

structResolver{func message(context:Context, arguments:NoArguments)async->Message{awaitsomeAsyncMethodToGetMessage()}}

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.

Support

This package supports Swift versions in alignment with Swift NIO.

Contributing

This repo uses the standard swift format, and includes lint checks to enforce these formatting standards. To format your code, run:

swift format --parallel --in-place --recursive ./

License

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

About

The Swift GraphQL Schema builder for macOS and Linux

Topics

Resources

Stars

562 stars

Watchers

15 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Graphiti

PlatformsVersionsLicenseGitHub Actions

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

To expose your schema through HTTP, check out graphql-vapor or graphql-hummingbird, and to generate Swift code from GraphQL SDL files, use graphql-generator instead.

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
letpackage=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.

structMessage:Codable{letcontent: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.

structContext{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
structResolver{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.

structMessageAPI:API{letresolver:Resolverletschema:Schema<Resolver,Context>}letapi=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
letbuilder=SchemaBuilder(Resolver.self,Context.self)
builder.add(Type(Message.self){Field("content", at: \.content)})
builder.query.add(Field("message", at:Resolver.message))letschema=try builder.build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)
PartialSchema implementation
finalclassChatSchema:PartialSchema<Resolver,Context>{@TypeDefinitionspublicoverridevartypes:Types{Type(Message.self){Field("content", at: \.content)}}@FieldDefinitionspublicoverridevarquery:Fields{Field("message", at:Resolver.message)}}letschema=trySchemaBuilder(Resolver.self,Context.self).use(partials:[ChatSchema(),...]).build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)
PartialSchema instance
letchatSchema=PartialSchema<Resolver,Context>(
types:{Type(Message.self){Field("content", at: \.content)}},
query:{Field("message", at:Resolver.message)})letschema=trySchemaBuilder(Resolver.self,Context.self).use(partials:[chatSchema,...]).build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)

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

Querying

letresult=tryawait api.execute(
request:"{ message { content } }",
context:Context())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:

structResolver{func message(context:Context, arguments:NoArguments)async->Message{awaitsomeAsyncMethodToGetMessage()}}

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.

Support

This package supports Swift versions in alignment with Swift NIO.

Contributing

This repo uses the standard swift format, and includes lint checks to enforce these formatting standards. To format your code, run:

swift format --parallel --in-place --recursive ./

License

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

About

The Swift GraphQL Schema builder for macOS and Linux

Topics

Resources

Stars

562 stars

Watchers

15 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Graphiti

PlatformsVersionsLicenseGitHub Actions

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

To expose your schema through HTTP, check out graphql-vapor or graphql-hummingbird, and to generate Swift code from GraphQL SDL files, use graphql-generator instead.

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
letpackage=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.

structMessage:Codable{letcontent: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.

structContext{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
structResolver{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.

structMessageAPI:API{letresolver:Resolverletschema:Schema<Resolver,Context>}letapi=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
letbuilder=SchemaBuilder(Resolver.self,Context.self)
builder.add(Type(Message.self){Field("content", at: \.content)})
builder.query.add(Field("message", at:Resolver.message))letschema=try builder.build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)
PartialSchema implementation
finalclassChatSchema:PartialSchema<Resolver,Context>{@TypeDefinitionspublicoverridevartypes:Types{Type(Message.self){Field("content", at: \.content)}}@FieldDefinitionspublicoverridevarquery:Fields{Field("message", at:Resolver.message)}}letschema=trySchemaBuilder(Resolver.self,Context.self).use(partials:[ChatSchema(),...]).build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)
PartialSchema instance
letchatSchema=PartialSchema<Resolver,Context>(
types:{Type(Message.self){Field("content", at: \.content)}},
query:{Field("message", at:Resolver.message)})letschema=trySchemaBuilder(Resolver.self,Context.self).use(partials:[chatSchema,...]).build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)

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

Querying

letresult=tryawait api.execute(
request:"{ message { content } }",
context:Context())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:

structResolver{func message(context:Context, arguments:NoArguments)async->Message{awaitsomeAsyncMethodToGetMessage()}}

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.

Support

This package supports Swift versions in alignment with Swift NIO.

Contributing

This repo uses the standard swift format, and includes lint checks to enforce these formatting standards. To format your code, run:

swift format --parallel --in-place --recursive ./

License

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

About

The Swift GraphQL Schema builder for macOS and Linux

Topics

Resources

Stars

562 stars

Watchers

15 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Graphiti

PlatformsVersionsLicenseGitHub Actions

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

To expose your schema through HTTP, check out graphql-vapor or graphql-hummingbird, and to generate Swift code from GraphQL SDL files, use graphql-generator instead.

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
letpackage=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.

structMessage:Codable{letcontent: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.

structContext{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
structResolver{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.

structMessageAPI:API{letresolver:Resolverletschema:Schema<Resolver,Context>}letapi=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
letbuilder=SchemaBuilder(Resolver.self,Context.self)
builder.add(Type(Message.self){Field("content", at: \.content)})
builder.query.add(Field("message", at:Resolver.message))letschema=try builder.build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)
PartialSchema implementation
finalclassChatSchema:PartialSchema<Resolver,Context>{@TypeDefinitionspublicoverridevartypes:Types{Type(Message.self){Field("content", at: \.content)}}@FieldDefinitionspublicoverridevarquery:Fields{Field("message", at:Resolver.message)}}letschema=trySchemaBuilder(Resolver.self,Context.self).use(partials:[ChatSchema(),...]).build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)
PartialSchema instance
letchatSchema=PartialSchema<Resolver,Context>(
types:{Type(Message.self){Field("content", at: \.content)}},
query:{Field("message", at:Resolver.message)})letschema=trySchemaBuilder(Resolver.self,Context.self).use(partials:[chatSchema,...]).build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)

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

Querying

letresult=tryawait api.execute(
request:"{ message { content } }",
context:Context())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:

structResolver{func message(context:Context, arguments:NoArguments)async->Message{awaitsomeAsyncMethodToGetMessage()}}

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.

Support

This package supports Swift versions in alignment with Swift NIO.

Contributing

This repo uses the standard swift format, and includes lint checks to enforce these formatting standards. To format your code, run:

swift format --parallel --in-place --recursive ./

License

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

About

The Swift GraphQL Schema builder for macOS and Linux

Topics

Resources

Stars

562 stars

Watchers

15 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Graphiti

PlatformsVersionsLicenseGitHub Actions

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

To expose your schema through HTTP, check out graphql-vapor or graphql-hummingbird, and to generate Swift code from GraphQL SDL files, use graphql-generator instead.

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
letpackage=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.

structMessage:Codable{letcontent: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.

structContext{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
structResolver{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.

structMessageAPI:API{letresolver:Resolverletschema:Schema<Resolver,Context>}letapi=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
letbuilder=SchemaBuilder(Resolver.self,Context.self)
builder.add(Type(Message.self){Field("content", at: \.content)})
builder.query.add(Field("message", at:Resolver.message))letschema=try builder.build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)
PartialSchema implementation
finalclassChatSchema:PartialSchema<Resolver,Context>{@TypeDefinitionspublicoverridevartypes:Types{Type(Message.self){Field("content", at: \.content)}}@FieldDefinitionspublicoverridevarquery:Fields{Field("message", at:Resolver.message)}}letschema=trySchemaBuilder(Resolver.self,Context.self).use(partials:[ChatSchema(),...]).build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)
PartialSchema instance
letchatSchema=PartialSchema<Resolver,Context>(
types:{Type(Message.self){Field("content", at: \.content)}},
query:{Field("message", at:Resolver.message)})letschema=trySchemaBuilder(Resolver.self,Context.self).use(partials:[chatSchema,...]).build()letapi=MessageAPI(
resolver:Resolver()
schema: schema
)

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

Querying

letresult=tryawait api.execute(
request:"{ message { content } }",
context:Context())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:

structResolver{func message(context:Context, arguments:NoArguments)async->Message{awaitsomeAsyncMethodToGetMessage()}}

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.

Support

This package supports Swift versions in alignment with Swift NIO.

Contributing

This repo uses the standard swift format, and includes lint checks to enforce these formatting standards. To format your code, run:

swift format --parallel --in-place --recursive ./

License

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

About

The Swift GraphQL Schema builder for macOS and Linux

Topics

Resources

Stars

562 stars

Watchers

15 watching

Forks

Releases

Packages

Used by

Contributors

Languages