tailcallhq / tailcall Goto Github PK
View Code? Open in Web Editor NEWA high-performance GraphQL Platform
Home Page: https://tailcall.run
License: Apache License 2.0
A high-performance GraphQL Platform
Home Page: https://tailcall.run
License: Apache License 2.0
Description:
When a tailcall server is configured without a resolver at the root level, it starts successfully. However, it doesn't respond to any requests, which can be misleading for developers. This behavior should be addressed by enforcing the presence of a resolver at compile time.
Reproduction Steps:
Example Configuration with Issue:
type Query {
user: [User]! # Unresolved root level configuration
}
type User {
id: ID
name: String
posts: [Post] @http(path: "/posts/{{value.id}}")
}
Proposed Solution:
If a configuration lacks a resolver at the root level and none can be inferred, a compile-time error should be thrown, clearly indicating the absence of a necessary resolver. This ensures that developers are aware of the missing resolver before runtime.
Update 1
This should only be applicable for scenarios where the type of the field is required. In a scenario where the field is not required, it's totally fine if there are no resolvers.
This happens when you run the tests a couple of times in sequence.
WARNING: An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
java.lang.OutOfMemoryError: Direct buffer memory
at java.base/java.nio.Bits.reserveMemory(Bits.java:175)
at java.base/java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:118)
at java.base/java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:317)
at io.netty.buffer.PoolArena$DirectArena.allocateDirect(PoolArena.java:632)
at io.netty.buffer.PoolArena$DirectArena.newChunk(PoolArena.java:607)
at io.netty.buffer.PoolArena.allocateNormal(PoolArena.java:202)
at io.netty.buffer.PoolArena.tcacheAllocateSmall(PoolArena.java:172)
at io.netty.buffer.PoolArena.allocate(PoolArena.java:134)
at io.netty.buffer.PoolArena.allocate(PoolArena.java:126)
at io.netty.buffer.PooledByteBufAllocator.newDirectBuffer(PooledByteBufAllocator.java:395)
at io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:188)
at io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:179)
at io.netty.buffer.AbstractByteBufAllocator.ioBuffer(AbstractByteBufAllocator.java:140)
at io.netty.channel.DefaultMaxMessagesRecvByteBufAllocator$MaxMessageHandle.allocate(DefaultMaxMessagesRecvByteBufAllocator.java:114)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:150)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:829)
Description:
The current compiler does not catch potential issues when a field that can be undefined or optional is used in the route parameter of Http. To enhance robustness and provide clearer developer feedback, the compiler should be improved in the following areas:
Potentially Undefined Route Parameter:
When a field that can be undefined or optional is used in the route parameter of Http, the code should not compile to prevent potential runtime issues.
Examples:
type Query {
user(id: Int): User @http(path: "/user/{{args.id}}")
}
In this first example, since id
is an optional parameter, using it directly in the route should trigger a compiler error.
type Post {
id: ID
userId: ID
user: User @http(path: "/users/{{value.userId}}")
}
In the second example, the userId
field is not guaranteed to always be present in a Post
. Using it in the path
should also raise a compiler error, as it can lead to unexpected behavior or failures.
Undefined References:
The compiler should be enhanced to detect any values, fields, arguments, etc. that are used but not defined, and raise appropriate errors.
We have recognized a recurring problem concerning the maintenance and susceptibility to errors when manually writing a codec for each modification in our Config structure. The existing process of employing Config2Document and Document2Config transcoders for these changes is resource-intensive.
To rectify this, we propose creating a Universal Codec, which will replace the individual transcoders. This codec will facilitate efficient conversion between Config and Document and vice versa, and crucially, it will handle changes in the Config structure without needing a rewrite.
Our plan is to develop this Universal Codec leveraging the power of ZIO Schema and our existing Directive Codec. Building on ZIO Schema allows us to derive codecs automatically based on the schema of the data. By doing so, we can deprecate the Config2Document and Document2Config transcoders, thereby reducing maintenance overhead, and improving our code's efficiency and reliability.
We will post updates on this issue as we progress with this implementation. Your feedback or suggestions are always welcome. We are looking forward to this significant improvement in handling Config and Document conversions.
requesting the blueprint when not found, results in an error. This is cached and even after publishing doesn't get fixed.
Homebrew is a standard way to install CLI applications for mac users. Ideally we would want to give developers a similar experience.
> brew install tailcall
> tc --help
After a release has been made, we should update a homebrew formula with the latest version automatically.
Create an encoder service that converts an Open API Specification into a list of Encoder.
Requirements
trait OpenAPIEndpointEncoder {
def encode(api: OpenAPI): List[Endpoint]
}
object OpenAPIEndpointEncoder {
final case class Live() extends OpenAPIEndpointEncoder {
override def encode(api: OpenAPI): List[Endpoint] = ???
}
}
Update Tailcall documentation with an example of composing rest endpoints into a graphql schema
Sample Usage
type User {
id: ID
name: String
}
type UserQuery @extends(type: "User") {
posts: [Post] @http(path: "/users/{{value.id}}/posts")
comments: [Comment] @http(path: "/users/{{value.id}}/comments")
}
type Post {
id: Int!
userId: Int!
title: String!
body: String!
user: User @http(path: "/users/{{value.userId}}")
comments: [Comment] @http(path: "/posts/{{value.id}}/comments")
}
type Query {
users: [UserQuery] @http(path: "/users")
posts: [Post] @http(path: "/posts")
}
In the above example you can request for UserQuery
from root Query and perform a deeply nested query. This makes sense at root level, however, if we don't want to provide this capability for other types such as Post, we create a new type called User
which has a limited set of fields. This way we restrict the kind of queries that can be made by client and provide stronger compile time performance guarantees specially around N + 1 API calls.
Implementation
Validations -
@extends
directiveType Generation - Two types are generated with a common set of defined in the base type. An Interface from the base type called IUser
is generated which is implemented by User
and UserQuery
interface IUser {
id: ID
name: String
}
type User implements IUser {
id: ID
name: String
}
type UserQuery implements IUser {
id: ID
name: String
# .. rest of the UserQuery fields
}
# rest of the types
Resolver - Should base type resolvers should be copied to the child resolvers (practically we copy the complete field)
NOTE:
@modify
should not be possible on fields that are being implemented via an interface. Compiler should throw an error when modify
is used this way.
For the user interface be it YML/JSON or a WEB UI, we should be able to use standard JQ syntax for accessing deeply nested values. Currently, mustache uses .
to access deeply nested values, but it's not very standard. Using JQ syntax we can make it easier for developers consume the DSL.
Proposal
The proposed way is to extend the mustache parser with support for JQ syntax.
References
https://stedolan.github.io/jq/tutorial/
Currently, the Remote library does not include the Seq class or its corresponding methods. This issue aims to implement Seq and its operators in Remote, including all standard library methods. Additionally, we propose to refactor the Map implementation by dropping redundant operators and implementing it via sequence.
To achieve this, we will need to:
Implement the Seq class in Remote.
Implement all standard library methods of Seq, such as map, filter, flatMap, etc.
Refactor the Map implementation to drop redundant operators such as concat, remove etc.
Tasks:
References
Can find references to operators here โ https://docs.scala-lang.org/overviews/collections-2.13/seqs.html#inner-main
Currently, the Remote DSL for Scala lacks several important Map operators, including ++
, --
, and getOrElseUpdate
. These operators are crucial for working with Scala Maps in a concise and expressive way, and their absence in the Remote DSL is limiting the functionality of the library.
I propose that we add these missing operators to the Remote DSL. Specifically, we should add the following methods to the MapOps trait:
These operators should be implemented in a way that is consistent with the existing Map operators in the Remote DSL, and with the Scala standard library.
Feel free to list down and add other standard Scala Map operators.
Identifying blueprints by hash is not developer friendly. There are to main issues with it โ
The proposal is to use semantic versioning for blueprints. So one could query schemas as - /graphq/0.1.2
Future Improvements
One could also query using filters such as /graphql/^0.1.2
, [find out more].(https://docs.npmjs.com/about-semantic-versioning)
Working
We will add a new cli feature tag
which will allow developers to tag a version once published. It would work as follows โ
> tc publish ./jsonplaceholder.graphql
Deployment was completed successfully.
Digest: b80aca49a8061f74d04245fdbf975b8b4565b232a257497c0e65d15ec7d97d77
Endpoints: 19
Unsafe: 0
Playground: https://cloud.tailcall.run/graphql/b80aca49a8061f74d04245fdbf975b8b4565b232a257497c0e65d15ec7d97d77.
N + 1: 19
๐ Completed in 1369 ms.
tag
to tag the published schema. The --auto
flag will infer a semantic tag and insert it.> tc tag b80aca49a8061f74d04245fdbf975b8b4565b232a257497c0e65d15ec7d97d77 --auto
Deployment tagged successfully.
Digest: b80aca49a8061f74d04245fdbf975b8b4565b232a257497c0e65d15ec7d97d77
Endpoints: 19
Unsafe: 0
Playground:
Tags: v1.2.0
๐ Completed in 136 ms.
Note
Currently its a lot of work to type out every field while implementing interfaces. This is something our compiler can do automatically. Fields that have not been implemented should be automatically copied from the interface.
0.x.x
until a stable 1.0.0
is released.Use graphql spec files to replace Config building logic in ConfigExecutionSpec
(similar to ConfigPropertySpec
)
Config.Server has support for specifying vars. Essentially global variables that can be used anywhere. This should be passed as context but isn't at the moment.
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
These updates have been manually edited so Renovate will no longer make changes. To discard all commits and start over, click on a checkbox.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.
Cargo.toml
mimalloc 0.1.39
http-cache-reqwest 0.13.0
moka 0.12.6
hyper-rustls 0.25.0
rustls 0.23.3
rustls-pki-types 1.4.1
inquire 0.7.4
opentelemetry-otlp 0.15.0
opentelemetry-system-metrics 0.1.8
rustls-pemfile 1.0.4
schemars 0.8.16
hyper 0.14
derive_setters 0.1.6
thiserror 1.0.58
serde_json 1.0
serde 1.0
serde_qs 0.13
serde_yaml 0.9
serde_urlencoded 0.7.1
url 2
reqwest 0.11
once_cell 1.19.0
clap 4.5.4
colored 2
regex 1.10.4
reqwest-middleware 0.2.5
async-trait 0.1.80
serde_path_to_error 0.1.16
cache_control 0.2.0
nom 7.1.3
exitcode 1.1.2
resource 0.5.0
stripmargin 0.1.1
num_cpus 1.16.0
fnv 1.0.7
futures-channel 0.3.30
futures-timer 3.0.3
lru 0.12.3
webbrowser 0.8.15
async-std 1.12.0
ttl_cache 0.5.1
protox 0.6.0
protox-parse 0.6.0
prost-reflect 0.13.1
prost 0.12.4
update-informer 1.1.0
lazy_static 1.4.0
which 6.0.1
async-recursion 1.1.0
tempfile 3.10.1
deno_core 0.274.0
strum_macros 0.26.2
tracing 0.1.40
tracing-subscriber 0.3.18
tracing-opentelemetry 0.23.0
getrandom 0.2.14
prometheus 0.13.3
tonic 0.11.0
opentelemetry-semantic-conventions 0.14.0
opentelemetry 0.22.0
opentelemetry_sdk 0.22.1
opentelemetry-http 0.11.1
opentelemetry-stdout 0.3.0
opentelemetry-appender-tracing 0.3.0
opentelemetry-prometheus 0.15.0
phonenumber 0.3.4
chrono 0.4.37
headers 0.3.9
mime 0.3.17
jsonwebtoken 9.3.0
async-graphql-value 7.0.3
dotenvy 0.15
convert_case 0.6.0
rand 0.8.5
criterion 0.5.1
httpmock 0.7.0
pretty_assertions 1.4.0
stripmargin 0.1.1
markdown 1.0.0-alpha.16
tempfile 3.10.1
temp-env 0.3.6
maplit 1.0.2
anyhow 1.0.82
async-graphql 7.0.3
futures-util 0.3.30
indexmap 2.2
insta 1.38.0
tokio 1.37.0
tailcall-autogen/Cargo.toml
anyhow 1.0.82
lazy_static 1.4.0
schemars 0.8.16
serde 1.0.197
serde_json 1.0.115
tokio 1.37.0
tracing 0.1.40
tailcall-aws-lambda/Cargo.toml
lambda_http 0.11.1
lambda_runtime 0.11.1
tokio 1
tracing 0.1
tracing-subscriber 0.3
dotenvy 0.15
anyhow 1.0.82
async-trait 0.1.80
hyper 0.14
reqwest 0.11
tailcall-cloudflare/Cargo.toml
hyper 0.14
worker 0.1.0
lazy_static 1.4.0
anyhow 1.0.82
async-trait 0.1.80
reqwest 0.11
async-std 1.12.0
tracing 0.1.40
tracing-subscriber 0.3.18
tracing-subscriber-wasm 0.1.0
serde_json 1.0.115
serde_qs 0.13.0
console_error_panic_hook 0.1.7
protox 0.6.0
async-graphql-value 7.0.3
tailcall-query-plan/Cargo.toml
async-recursion 1.1.0
indenter 0.3.3
dashmap 5.5.3
Dockerfile
.github/workflows/benchmark.yml
actions/checkout v4
actions-rust-lang/setup-rust-toolchain v1
actions/upload-artifact v4
actions/checkout v4
actions-rust-lang/setup-rust-toolchain v1
actions/cache v4
actions/checkout v4
actions-rust-lang/setup-rust-toolchain v1
actions/cache v4
.github/workflows/build-website.yml
.github/workflows/ci.yml
actions/checkout v4
actions/checkout v4
actions-rust-lang/setup-rust-toolchain v1
actions/setup-python v5
actions/checkout v4
actions-rust-lang/setup-rust-toolchain v1
actions/setup-node v4
actions/checkout v4
actions-rust-lang/setup-rust-toolchain v1
Wandalen/wretry.action v2
actions/checkout v4
actions-rs/toolchain v1
actions-rust-lang/setup-rust-toolchain v1
actions/checkout v4
release-drafter/release-drafter v6
actions/checkout v4
actions-rust-lang/setup-rust-toolchain v1
ClementTsang/cargo-action v0.0.6
actions/setup-node v4
JS-DevTools/npm-publish v3
xresloader/upload-to-github-release v1
actions/checkout v4
actions-rust-lang/setup-rust-toolchain v1
actions/setup-python v5
xresloader/upload-to-github-release v1
test-room-7/action-publish-release-drafts v0
actions/checkout v4
actions/setup-node v4
JS-DevTools/npm-publish v3
actions/checkout v4
docker/login-action v3
docker/metadata-action v5
docker/build-push-action v5
actions/checkout v4
.github/workflows/comment-commit.yml
actions/download-artifact v4
peter-evans/commit-comment v3
.github/workflows/labels.yml
actions/checkout v4
.github/workflows/lint.yml
actions/checkout v4
actions/setup-node v4
actions-rust-lang/setup-rust-toolchain v1
autofix-ci/action ea32e3a12414e6d3183163c3424a7d7a8631ad84
.github/workflows/pr-convention.yml
amannn/action-semantic-pull-request v5
.github/workflows/release-drafter.yml
release-drafter/release-drafter v6
.github/workflows/release.yml
actions/checkout v4
.github/workflows/stale.yml
actions/stale v9
npm/package.json
ts-command-line-args ^2.5.1
type-fest ^4.7.1
yaml ^2.3.3
yml ^1.0.0
tsx ^4.1.0
tailcall-cloudflare/package.json
miniflare ^3.20231218.3
vitest ^1.2.1
wrangler ^3.24.0
@cloudflare/workers-types ^4.20240117.0
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.