Comments (36)
I'm working on this, it's going well, and a preview will be released this week. π
from async-graphql.
I opened a PR to track progress.
from async-graphql.
I think we should probably add an execution phase validator called Guard
.
from async-graphql.
Yep, dynamic schema would definitely be something of interest.
I'm currently building a "hacky" way to do this as it's not properly supported anywhere, for example in my project I need to have
RecordType {
...
schema: JSONMap
}
and Record {
recordTypeId: ..
data: JSONMap (this data is being validated using a json schema from RecordType)
}
And I'd like to support some sort of querying by these dynamic fields. At the moment I'm looking at custom implementation for this as this is tricky and not really supported by the graphql spec, considering that in the example above each RecordType might have a different schema.
But, getting back to reality - it would be nice to support dynamic schema!
from async-graphql.
I think we should probably add an execution phase validator called
Guard
.
Yeah, that would be awesome.
If you need a context, the
Validator
can't do that right now, because it's in the query validation phase, and it hasn't created a context yet.π
Yeah, I have figured as much.
from async-graphql.
Thank you, that gave me some inspiration, and I'm working on that right now.
from async-graphql.
One important feature I overlooked is that guard can be applied to the SimpleObject.
from async-graphql.
@sunli829, what became of this issue? I wasn't able to follow along properly to understand if this was implemented. There was mention of passing new schemas to validators and not having a context available. Then there was discussion about a guard and it looks like that was implemented, although I don't recall seeing guards mentioned in the book.
A use case I have in mind is enabling users of vimwiki-server to define custom logic that can leverage the data models I've built for the vimwiki language and respond to some custom query using an embedded language like Lua that connects to the Rust server.
My only thought right now without some way to define a custom schema alongside my static schema is through some general-purpose query:
{
lua_query(key: "some identifier", input: "some input") {
key
output
}
}
from async-graphql.
Am I right in thinking that dynamic schemas would also be needed to implement an Apollo Gateway replacement in rust?
Yes, you are absolutely correct. π
from async-graphql.
Dynamic schemas would be a big win for my production work. I have/am developing a system for the company I work for which allows us to add/remove/change our systems behavior at runtime using a series of configuration files, part of which is being able to manipulate our webserver/graphql interface. Right now I have to use a super generic interface that works for all situations but isn't ideal due to how vague it is.
from async-graphql.
@Bjohnson131 Please take a look at https://github.com/apollographql/apollo-rs
Currently, if you want to implement a dynamic schema, you have to implement it by yourself. Use apollo-encoder to generate a schema SDL and apollo-parser to parse GraphQL requests.
from async-graphql.
Iβm relatively new to GraphQL and havenβt encountered dynamic schemas. Could you provide a link? Or an example use-case?
from async-graphql.
https://github.com/graphql-go/graphql
Like this, allows change schema at run time.
Not code generation, no type safety, and poor performance.
from async-graphql.
Alright so here is a somewhat incomplete and unordered list of thoughts:
Cons
- The effort of implementing it.
- People might choose a not ideal implementation for their problem because they are unaware of the cost.
Pros
-
The task of handling dynamic schemas is expensive in every language and I would always prefer to implement an inefficient task in a fast language than in a slow one.
-
dynamic schemas in rust would still outperform implementations in most other languages + give you still a decent amount of typesafety which is important because you might have no control over the schemas you are serving.
-
Can be handy for rapid prototyping.
-
Not every project needs top performance.
-
Sometimes usability is key. Eg. a service implementing a graphql endpoint for maintenance or admins etc.
-
If implementing dynamic schemas means decoupling the logic from the codegen then you get even more benefits. It becomes easier to
-
add new features like flatten fields for example.
-
add new crates like an async-graphql-client which depends on the same core types.
-
-
I would:
-
prepare the codebase by extracting the core functionality.
-
implement it on top of the core.
-
make it a feature which is disabled by default.
-
clearly state in the docs that static schemas. are to be preferred over dynamic schemas where ever possible.
-
Show benchmarks of dynamic vs static.
-
from async-graphql.
I tried it out yesterday, but it didn't workπ, and I'm still thinking about a better way to do it. The main reason is that rust does not support generic specialization, solving the problem with newtype
makes the library particularly verbose to use.
from async-graphql.
I will definitely π when specialization lands on stable rust.
from async-graphql.
Have you looked at the Syllogism crate for specialization?
from async-graphql.
Thank you for telling me about Syllogism
crate. I'll see if it works for me. π
from async-graphql.
Validation the JSONMap you could try async_graphql::InputValueValidator
.
from async-graphql.
@sunli829 I'll give it a shot, I can probably integrate that with http://rustless.org/valico/doc/valico/
from async-graphql.
This should solve the problem perfectly.π
from async-graphql.
@sunli829 yeah, except I need to pass said schema to the validator.
That would be possible if the context got passed to the validator as well, so that I could go to the database and check, otherwise I can't see how to implement this. But it's alright if I just have to check within the mutation body.
from async-graphql.
If you need a context, the Validator
can't do that right now, because it's in the query validation phase, and it hasn't created a context yet.π
from async-graphql.
@sunli829 should I add a ticket for Guard
?
I'd contribute it myself, but so far a bit swamped with other coding duties :/
from async-graphql.
This should be finished by tomorrow. I have been trying other improvements for the last two days.
from async-graphql.
Curious to see what you came up with for other issues we had!
from async-graphql.
In fact, I'm still thinking about how to use Guard
, because even without this feature, a single line of code can solve the problem.
#[field(guard="require_auth")
async fn value(&self) -> i32 {...}
async fn value(&self, ctx: &Context<'_>) -> FieldResult<i32> {
require_auth(ctx)?;
}
The guard attribute doesn't offer any convenience, and I'm still wondering if this feature is necessary.
from async-graphql.
Curious to see what you came up with for other issues we had!
I tried to optimize the way the interface is defined, but I was not satisfied with either approach.
from async-graphql.
In fact, I'm still thinking about how to use
Guard
, because even without this feature, a single line of code can solve the problem.#[field(guard="require_auth") async fn value(&self) -> i32 {...}async fn value(&self, ctx: &Context<'_>) -> FieldResult<i32> { require_auth(ctx)?; }The guard attribute doesn't offer any convenience, and I'm still wondering if this feature is necessary.
That actually seems very nice to me, because then we could apply several guards as well, and that's several method calls.
If we could also specify params for the guards - even better. For example, field(guard="require_auth(role=ADMIN)")
or similar.
Take a look at some of the features of https://docs.nestjs.com/graphql/tooling for inspiration, they have some powerful annotations in place that make working with graphql a blast!
from async-graphql.
One important feature I overlooked is that guard can be applied to the SimpleObject.
Yeah, I mean there are plenty of nice looking features there, but not all of them can be implemented in rust the same way, as it's not the same.
For example, there is an ability to annotate methods and types so that they end up being parts of the query/mutation/subscription without actually being one object AFAIK. That allows for splitting the schema by functionality, we could kind of mimic that by having a composite struct I suppose.
from async-graphql.
I created a new issue #43, adding this feature was more difficult than I expected, I needed to modify some code generation, and it probably took a little longer to complete.
from async-graphql.
Am I right in thinking that dynamic schemas would also be needed to implement an Apollo Gateway replacement in rust?
from async-graphql.
Hey @sunli829 you closed this as completed
. was there a PR for this feature that I can look at?
from async-graphql.
I underestimated the amount of work, but it should be done this week.
from async-graphql.
This is so big! If you get a preview, let me know! I'll be following!
from async-graphql.
This issue can be probably closed
from async-graphql.
Related Issues (20)
- Confusing `unused_mut` warning in `#[Object]` HOT 8
- How to handle both directions of one-to-many relation in federated graph
- Question: How to get server to send ping messages on subscriptions? HOT 2
- Parsing multiple operations in a file HOT 1
- Non nullable variables should allow default values HOT 3
- Object with single skipped field but with ComplexObject HOT 2
- As using proxy type
- Using flatten inside an impl with no other fields causes a compile error
- Subscription with MPSC receiver in context data
- Reduce clippy noise from #[Object] macro HOT 2
- Guard trait lifetime HOT 1
- Using generics with both SimpleObject and InputObject as field in output type fails HOT 1
- Subscription Authentication
- Stack overflow after upgrade to 7.0.2 HOT 5
- Does async-graphql validate responses?
- Error reading data from ExtensionContext after upgrade to 7.0.3 HOT 1
- Create a general error formateer
- Allow flatten on arguments HOT 1
- External fields not getting generated in SDL
- Overflow when using `MergedObject`
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from async-graphql.