FrontPage SiteMap RecentChanges HowTo Blog

Matching Pages:

RSS

HttpStubs

Discussion

Does anyone know of anything like what I'm calling "HTTP stubs?"

Basically, it goes like this: You'd have an interface that says something like:

 <httpinterface>
   <title>Oddmuse Interface</title>
   <description>yadda yadda yadda</description>
   <separator>;</separator>
   <action>
     <title>edit</title>
     <description>edit a wiki page</description>
     <method>GET</method>
     <arg>
       <title>contents</title>
       <type>string</type>
       <form>page</form>
       ...
     </arg>
     <arg>
       ...
     </arg>
   </action>
   <action>
     ...
   </action>
 </httpinterface>

Then, from the interface description, you could generate stubs, for Python, Perl, PHP, whatever languages, automatically.

You can also generate HTML form pages or page fragments.

HttpStubsImage

You could also write skeletons or skeleton-adapters for various languages.

These skeletons could include built-in help documentation, so that "action=help" is implicitely defined for all these services. There'd also be response of the interface definition itself. (That is, you could dynamically query for the raw HTTP interace description.)

This is basically like SOAP, except for HTTP raw interface, which some people seem to prefer.

There's just so much tedium involved in making a simple raw HTTP web service, it feels like it shouldn't be there.

I remember some blogger mentioning something about raw HTTP interface standards, but I don't remember where,… If I recall right, nobody really responded to the call.

There seems to be something called HTTP-NG, but I can't say I really get it, after quickly looking over it.

If I were to write an interface definition, it would be in XML, and look something like this:

  • <httpinterface>
    • <title> - string title
    • <short> - line telling what the interface is about
    • <description> - paragraph telling what the interface is about
    • <separator> - i.e. "&" or ";"
    • <actionkey> - i.e. "action" or "method" or "do"
    • <action>
      • <name> - "edit" or "dump-cache" or whatever invokes the action
      • <short>
      • <description>
      • <method> - "get" or "post"
      • <example> - example of use, beginning with ?action=…
      • <arg>
        • <name> - name of argument
        • <short>
        • <description>
        • <type> - "string" or "int"
        • <min> - minimum # of occurrances
        • <max> - max # of occurances
        • <form> - for rendering to forms, either "short" or "line" or "page" (loose definition)
      • <result>
        • <short>
        • <description>
        • <type>
        • <list/> - if present, means to separate results for client, into list, by newline

Something like that.

HttpStubsSchemaImage

Here's what a one-function interface might look like:

 <httpinterface>
   <title>Local Names Server</title>
   <short>Resolve names, manage cache</short>
   <description>The Local Names Server can use Local Names v1.1 namespace descriptions
     to resolve URLS. The interface lets you resolve names, and query and manage the
     namespace cache.</description>
   <actionkey>action</actionkey>
   <separator>&</separator>
   <action>
     <name>lookup</name>
     <short>Resolve a local name</short>
     <description>Resolve a local name. Namespace hopping is allowed. Namespace hops
       are designated by a separator in the lookup value.</description>
     <method>get</method>
     <example>?action=lookup&namespace=http://ln.taoriver.net/localnames.txt&separator=/&lookup=services/rfc/ftp</example>
     <arg>
       <name>namespace</name>
       <short>URL of namespace description</short>
       <description>URL of v1.1 Local Names namespace description. This is the namespace
         that resolution begins in.</description>
       <min>1</min>
       <max>1</max>
       <form>long</form>
     </arg>
     <arg>
       <name>lookup</name>
       <short>Lookup path</short>
       <description>Lookup path. This is the path that resolution follows. If the separator
         does not appear (path length 1,) then just look up this name in the namespace
         description. Otherwise, start traversing namespace links until reaching the final
         name in the final namespace.</description>
       <min>1</min>
       <form>long</form>
     </arg>
     <arg>
       <name>separator</name>
       <short>Lookup path separator</short>
       <description>Lookup path separator. This symbol, when appearing in the lookup path,
         separates names. All names but the last name namespaces, the last name names
         a name within a namespace.</description>
       <min>0</min>
       <max>1</max>
       <form>short</form>
       <default>/</default>
     </arg>
     <result>
       <short>Resulting URLs</short>
       <description>List of resulting URLs. Results that could not be found return as empty lines.</description>
       <type>string</type>
       <list/>
    </result>
   </action>
 </httpinterface>

Code that uses it might look like this:

 import httpinterface
 server = httpinterface.HttpInterface("http://services.taoriver.net:9090/")
 for action in server.actions:
   print "%s --  %s" % (action.name, action.description)  # Print action documentation
 urls = server.call("lookup", namespace="http://taoriver.net/tmp/gmail.txt", lookup="Lion Kimbro")
 urls2 = server.call("lookup", "http://taoriver.net/tmp/gmail.txt", ["Lion Kimbro", "Alex Schroeder", "Marshall Brain"])

HttpInterfacePythonImage

In this case, what happens is:

It's also possible to automatically create HTML forms that submit to the web service.

It is also possible to automatically generate help documentation, too, on either the client, the server, or a 3rd party server that consults the 1st server for it's XML HTTP interface description.

It's my belief that this sort of thing is mildly useful.

At the very least, it's personally useful, because I like to make a lot of web services, but dislike the process of writing documentation, the process of putting the server together, the process of putting together Python stubs, yadda yadda yadda. This can automate all that.

That said, SOAP does pretty much exactly this, just in infinitely greater grace and detail.

So why don't I use SOAP?

Because all my friends prefer HTTP interfaces. They all go, "Ewwwwww… SOAP!" Or: "Ewwwww… XML-RPC!"

I honestly don't understand it.

But my friends seem to want HTTP, and if that's what they want, I'm happy to grant it.

So, what would you think?

Is this something I should work on? Or should I just stick with SOAP or XML-RPC?-

I'm not sure… Does this really save that much work? When I look at the XML config file, I wonder whether the corresponding Perl code plus docu pages on the wiki would be about the same size and don't require anything beyond a basic CGI library. If we really did it like you descibe it here, we might as well use SOAP. People like me like to use HTTP directly because it is lean and mean. Using httpinterface.HttpInterface?("http://services.taoriver.net:9090/") seems an attempt at saving work for other contributors where we're not even sure yet it will take off. Premature optimization and all that. For one developer this proposal adds complexity instead of reducing it.

The motivation for this is:

  • I like to write lots of web services.
  • I dislike writing web service "hookup" code. You know- "when you get action=foo, call function foo." It's very tedious, and it's very boring.
  • I also dislike writing validation code. "Did they pass everything they were supposed to? They didn't? Oh, we better tell them about that!"
  • I really like naked web services- web services that tell you what they do, what arguments they take, stuff like that. I like to be able to hit it naked, with a web browser, and get back nice notes on everything it can do.
  • I like being able to debug web services by just typing into HTML forms.
  • I dislike writing HTML forms.
  • I like being able to use a web service with a module-level API.
  • I dislike concatenating and converting strings, packaging calls into url calls, and then unpackaging the results.
  • I like making changes to the way things work.
  • I dislike making the same change in 5 different places.

Doing it the "lean & mean" way, by hand, is extremely tedius.

  • I have to write the CGI handler.
  • I have to write the code that says, "Oh, they wanted action 'foo?' Call function foo."
  • I have to write code that packs and unpacks strings for arguments.
  • I have to write HTML forms.
  • I have to write documentation responses.
  • I have to correct my errors in performing all the above.

Now, you've mentioned complexity. What complexity?

It's an XML format. I thought it was pretty straight-forward.

I can imagine tools. They would look something like:

 import httpstubs
 class LocalNamesResolver:
     def lookup(namespace, lookup, separator):
         do_some_stuff()
         do_some_stuff()
         return result
 if __name__ == '__main__':
     server_class = HttpStubsServer.HttpStubsServer
     httpd = server_class((HOST_NAME, PORT_NUMBER), LocalNamesResolver)
     httpd.serve_forever()

This would give you a self-documenting server (both for humans and machines,) an HTTP API, and the server.

If you wanted it to be a CGI, I imagine just a few lines at the bottom would make that work.

I don't know; It just seems like a really good idea to me.

I'm honestly perplexed by the frequency that people tell me that these kinds of ideas are bad.

I have to conclude that it's some form of StopEnergy, for the following two reasons:

  • I am incapable of understanding the argument against the idea, despite attempts to understand.
  • The response fits what my mentors say I should expect. That is: people are seldom excited by good new ideas, and are full of reasons why they are bad or won't work.

Charles Babbage, Napoleon Hill, David Winer, and Tim Berner's Lee have all said these things. And many more.

So, please don't take it personally if I ignore it.

It honestly doesn't seem very complicated to me; And it honestly seems labor saving to me.

At the very least, on just a personal level, it makes it possible for me to write things that are extremely hard to write otherwise. (Writing them isn't hard. Writing them well and consistently is.)

I say we give it a try, then. :)

Thank you, Alex. :)

I'm getting to work on it, right now. :)

Define external redirect: HttpInterface

EditNearLinks: MeatballWiki WikiMatrix

Languages: