koding / kite

Micro-service framework in Go
https://godoc.org/github.com/koding/kite
MIT License
3.26k stars 300 forks source link

implement a method "kite.methods" #36

Open humanchimp opened 10 years ago

humanchimp commented 10 years ago

This method would return a representation of the signatures for all the methods of a kite:

{
    "square": [ "num", "callback" ],
    "pow": [ { "kwargs": [ "base", "exponent" ] }, "callback" ]
}

We can figure out what color to paint the bikeshed, and also discuss whether we want to also support optional type annotations. The idea is that it's a general faculty for finding out what methods are offered by a kite. On the JS side, we can automatically create method shims for each method so that instead of needing to do, say, kite.tell('getRiffiwobbles') we could more handily call kite.getRiffiwobbles(). Also, for the kite website, we can have a bunch of different kind of kites registered, but the javascript client does not need to know specifics about those kites in order to display UI that will let the user call the remote methods.

We could reflect the type information from the registered methods, and represent that in some way, so that the client could optionally validate the types of arguments it receives before sending the message. The type annotation part seems like a nice-to-have, but I think we do need method itself.

fatih commented 10 years ago

We can do it on the Go side with reflections. However there might some limitations, like getting the full function name for certain situations. Or passed callbacks.

I think we need to decide on the lowest common dominator and create a protocol. This would enable us at least to create more stable API's.

humanchimp commented 10 years ago

Bikeshedding aside for now, the lowest common denominator means:

Nice to have:

I think that the type annotations can really make this nice, but it's going to mean more work for us. I'd like it if we at least plan a way forward that can support implementing optional type annotations at some point in the future.

humanchimp commented 10 years ago

I'll take the first whack at a concrete protocol:

{
  "square": {
    "signatures": [
      [
        {
          "name": "num",
          "type": "float64"
        },
        {
          "name": "callback",
          "type": "function",
          "signatures": [
            [
              {
                "name": "squaredNum",
                "type": "float64"
              }
            ]
          ]
        }
      ]
    ]
  },
  "pow": {
    "signatures": [
      [
        {
          "name": "options",
          "type": "kwargs",
          "arguments": [
            {
              "name": "base",
              "type": "float64"
            },
            {
              "name": "exponent",
              "type": "float64"
            }
          ]
        },
        {
          "name": "callback",
          "type": "function",
          "signatures": [
            [
              {
                "name": "raisedNum",
                "type": "float64"
              }
            ]
          ]
        }
      ]
    ]
  }
}
fatih commented 10 years ago

There is no support for optional arguments on the Go side. Also I want to get rid of callbacks in the long term, supporting them is not a good thing.

I was thinking of a more simpler way, like (pseudo code, going to be JSON):

square: 
    Desc: "Returns the squared number"
    Input: ["integer"]
    Output: ["integer"]

Pow: 
    Desc: "Pow returns  the base-x exponential of y. x is the first arg, y is the second arg"
    Input: ["integer", "integer"]
    Output: ["integer"]

ping:
   Desc: "Responses with a pong message"
   Input: [ "string" ]
   Output: ["string"]

foo:
   Desc: "Foo is a method that let's you do Bar things"
   Input: [ "array", "int"]
   Output: ["string"]

That can be improved, but I was thinking of a more literal output. We should call it once and get the necessary methods once and build our applications around it.

humanchimp commented 10 years ago

Some feedback:

  1. we should use JSON, not YAML.
  2. Your proposal does not support "kwargs", which are needed.
  3. We need to support callbacks for now, even if there is a plan to remove support at some time in the future. "You go to war with the army you have—not the army you might want or wish to have at at a later time." :)
  4. You are listing only type annotations, but we need the names of the parameters more urgently than type annotation support.
humanchimp commented 10 years ago

Also, there is support for optional arguments in go, just not optional positional arguments. Go supports optional "kwargs" implemented as map[string]interface{}. Optional arguments are also supported in other programming languages targeted, notably JavaScript

fatih commented 10 years ago