Comments (21)
How about no change to the ruby code but have this built in input type.
input HttpInfo {
path: String!
header: [String]
}
Of course more fields than that but then in the request:
query myQuery($httpStuff: HttpInfo) {
lookAhead(info: $httpStuff)
}
Any variable with the HttpInfo type is automatically populated. Pretty clean this way I think.
from agoo.
�Done
from agoo.
The GraphQL spec does not cover that so there is currently no way to get that information. I am very willing to entertain some option to get at that information though. Obviously it is available internally so it is just a matter of how best to expose it. Let's discuss some options.
One approach would be to add an argument to the top level methods. Taking the songs.rb
example the Schema class looks like this, sort of, simplified a bit.
class Query
# methods go here
end
class Schema
attr_accessor :query
def initialize
@query = Query.new
end
end
Changing it to this
class Query
def initialize(request)
# request should have all header fields and other header stuff like the path and request method.
end
end
class Schema
def query(args={})
Query.new(args['_http_request_'])
end
end
from agoo.
That would work well for me at least.
Another wish: maybe at same time you could expose the whole graphql request? For nested queries I would prefer doing eager loading only when needed, now I have to do that always just in case.
from agoo.
Maybe with the same approach. That will require building a map of ruby objects. I might keep that separate. Let me see as I get into it.
from agoo.
I'd like your opinion on naming. I could make the name something like HttpRequest and ResolvePlan or to avoid collisions with user type names go with AgooRequest and AgooPlan.
from agoo.
In my case it does not matter, not mixing this with other http frameworks. Agoo-prefix should be more safe in overall.
from agoo.
The way the proposed feature would be used is like this:
query myQuery($req: AgooRequest!, $plan: AgooPlan) { hello }
When the AgooRequest or AgooPlan types are seen they are populated automatically. This requires the requestor to specify the variables. It mean an adhoc query from some client that does not include those would not pass the information on. Do you think that's an issue? If so I could reserve $agooReq
and $agooPlan
and make them magically available.
Here is the relevant schema. I think it covers what we are talking about.
input AgooRequest {
method: AgooMethod!
port: Int!
host: String!
path: String!
query: [AgooQuery!]
headers: [String!]!
}
input AgooQuery {
key: String!
value: [String!]!
}
input AgooPlan {
field: String!
args: [AgooArg]
directives: [AgooDirective]
fields: [AgooPlan]
}
input AgooArg {
name: String!
bool: Boolean
num: Int
dec: Float
str: String
}
input AgooDirective {
name: String!
args: [AgooArg]
}
from agoo.
Well, I would prefer keeping the interface towards our API clients clean. If I understood right, one would need to include these in the graphql request? I feel these are purely implementation issue and for public API I would not like to include such requirements, they don't need to know which framework we are running on.
I actually liked you previous idea that headers are received in query / mutation constructor. That way I can call it like this:
class Schema
def query(args={})
puts "query received #{args}"
Query.new(args)
end
def mutation(args={})
puts "mutation received #{args}"
Mutation.new(args)
end
end
class Mutation
attr_accessor :authenticator
def initialize(args={})
puts "mutation pay initialized with args #{args}"
self.authenticator = Authentication::DummyAuthenticator.new({user_id: 1, merchant_id: 1, shop_id: 1, device_id:1})
end
def pay(args={})
puts "mutation pay called with args #{args}"
res = Seamless.exec(:pay, {authenticator: self.authenticator}, Hashie.symbolize_keys!(args))
res&.results[:purchase][:model]
end
end
I could then just replace the Dummy authenticator with some real JWT-type of authenticator.
I have already implemented quite neat bridge between Agoo and my domain-models (using rom-rb), where I can automatically construct graphql interfaces using metaprogramming. Same will be applied for Mutations, so that these commands like "pay" above would automatically coming from the models. When we are ready I can share some examples on how to connect this with existing apps / models.
from agoo.
I understand and that makes sense. I'd like to find an approach that allows Agoo not to build the request or plan unless it has to since there is some overhead in doing so. How about something like this:
If the method signature takes a single argument as it is currently implemented then no request and no plan are created. If there are two arguments then the request info is provided, three args the method gets the plan as well. I think that covers not bringing the client into the mix.
from agoo.
That sounds like a good approach. With method signature you mean mutation and query methods in Schema?
from agoo.
Yes, the query, mutation, and subscription methods. I could make the plan available to all if that seems useful. I would flip the order of the 3 arguments if that is the case though for consistency although maybe all would like to have the option.
from agoo.
Just pushed a with-request
branch that includes access to the request. Just change the method signature to #my_method(args, req)
and the req
will be populated just like in the rack #call(req)
method.
from agoo.
Great to hear, I'll give it a try tomorrow
from agoo.
If you are interested in contributing a simple auth example that would be great. If not I'll put something together.
from agoo.
What do you think? Is the feature ready for a release?
from agoo.
Yes, I got it working and can now proceed on writing the authentication part. Will go to end of this month, so after that I could try to contribute few snippets. Few remarks about the implementation, would be good to update docs/examples:
- Seems you have removed arguments from Schema class methods (query, mutation and subscription) and now rely fully on actual graphql method. This is totally fine, just good to know.
- These arguments (arg & request) must not be with default-value. e.g. method_name(arg={}, req={}) does not pick the request object.
By the way, does Agoo nowadays "hijack" the Rack server ownership, e.g. from puma? I have a Gem that relies on Agoo and when added to Rails project, that seemed to open Agoo as rails server, at least in development environment.
from agoo.
The schema class methods can still take args and also requests. They are no different than any of the others or should not be anyway.
Yes, if there is a default value on any but the last the Ruby call to get arity
returns a lower value that what you and I see in the code. Maybe a bug or maybe intentional, I don't know but that is the way it is.
The GraphQL path takes precedence over other paths. If using Agoo with Rails puma is not involved. Agoo is a Rails server and significantly faster than puma in benchmarks.
from agoo.
I'd like to get this branch merged since I will be making changes in the same area as I start in HTTP/2. If there are no problems with the additional features I'll make the merge.
from agoo.
Please do proceed with merge. What I have played with this, it works well and will help me to continue my work. I will try to later contribute a bit with examples and snippets. Thanks, keep up the good work.
from agoo.
Great, thanks again for this! Have been on sidetrack last month, but after I get back on this, will try to contribute something back.
from agoo.
Related Issues (20)
- Fragment usage HOT 17
- CORS issues HOT 8
- Agoo dumps core on malformed SDL HOT 5
- fails to launch in clustered mode HOT 17
- Agoo Fragment Cycle Security Vulnerability HOT 2
- Disabling introspection for GraphQL HOT 12
- Changes on args or req does not get fowarded to the other calls HOT 9
- Static asset with space in filename HOT 4
- gem install agoo fails on MacOS Ventura 13.2.1 HOT 9
- Static .txt files are not served with utf-8 encoding HOT 8
- Agoo crash and exit HOT 7
- CLI options for SSL/TLS HOT 3
- localhost is crashing as bind address HOT 4
- 502 via nginx proxy_pass HOT 3
- TypeError: no implicit conversion of Array into String HOT 2
- rackup -r agoo -s agoo Doesn't Work HOT 8
- How to create a dynamic GraphQL schema HOT 6
- Configuring worker count and thread count when used with Rails HOT 5
- Port cleanup on shutdown? HOT 3
- REMOTE_ADDR not set on ENV HOT 13
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 agoo.