Giter Site home page Giter Site logo

Comments (21)

ohler55 avatar ohler55 commented on May 21, 2024 1

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.

ohler55 avatar ohler55 commented on May 21, 2024 1

�Done

from agoo.

ohler55 avatar ohler55 commented on May 21, 2024

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.

pasivuorio avatar pasivuorio commented on May 21, 2024

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.

ohler55 avatar ohler55 commented on May 21, 2024

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.

ohler55 avatar ohler55 commented on May 21, 2024

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.

pasivuorio avatar pasivuorio commented on May 21, 2024

In my case it does not matter, not mixing this with other http frameworks. Agoo-prefix should be more safe in overall.

from agoo.

ohler55 avatar ohler55 commented on May 21, 2024

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.

pasivuorio avatar pasivuorio commented on May 21, 2024

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.

ohler55 avatar ohler55 commented on May 21, 2024

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.

pasivuorio avatar pasivuorio commented on May 21, 2024

That sounds like a good approach. With method signature you mean mutation and query methods in Schema?

from agoo.

ohler55 avatar ohler55 commented on May 21, 2024

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.

ohler55 avatar ohler55 commented on May 21, 2024

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.

pasivuorio avatar pasivuorio commented on May 21, 2024

Great to hear, I'll give it a try tomorrow

from agoo.

ohler55 avatar ohler55 commented on May 21, 2024

If you are interested in contributing a simple auth example that would be great. If not I'll put something together.

from agoo.

ohler55 avatar ohler55 commented on May 21, 2024

What do you think? Is the feature ready for a release?

from agoo.

pasivuorio avatar pasivuorio commented on May 21, 2024

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.

ohler55 avatar ohler55 commented on May 21, 2024

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.

ohler55 avatar ohler55 commented on May 21, 2024

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.

pasivuorio avatar pasivuorio commented on May 21, 2024

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.

pasivuorio avatar pasivuorio commented on May 21, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.