several has asked for the wisdom of the Perl Monks concerning the following question:

Hi there,

I was wondering what shall I use these days in order to describe a REST/JSON WebService implemented in Mojolicious.

I did stumble over a few json description schemas, but either they are abandoned or not yet implemented:

Is there an adequate json webservice description language which would allow it to generate a CLI from a downloaded service description file? Any perl libs so far?

Thank you!

Replies are listed 'Best First'.
Re: JSON WebService Description with PERl
by Rhandom (Curate) on May 08, 2012 at 13:56 UTC
    I've dealt with WSDL and other representations. Coming from a mostly perl world, I really don't care for anything that I've seen. I just read the JSON-WSP service description you listed. It is a little better than WSDL, but only just a little. Most of the service description protocols seem to want to be able to wrap any function taking any type of arguments and returning any type of data. You can see this with various warts such as the doc_lines and def_order constructs of the JSON-WSP description. Those aren't really important details for what the method does - but represents an almost too literal representation of the underlying python library. I can see right off that it would make reordering the subroutine at a later date very problematic.

    I've built well over a dozen protocols for various services. Over the years they have all migrated towards JSON over HTTP. I've gotten to the point where I don't really care about being able to wrap any subroutine signature under the sun. I've given myself a very simple layout.

    1. I require a method name - I typically like to pass this along in the path info so that my access logs are more meaningful.
    2. My arguments coming in are always a hashref.
    3. My response is always a hashref.
    4. If there is an error situation, there will be a key in the response called "error."
    That is it. Those are all the rules. Exposing methods is always easy. Writing AJAX request/response handlers is always easy. Writing clients is always easy.

    Since I have an easy format to follow, my meta description service is easy to write to as well. If I exposed a method called "foo," I would also write an accompanying sub called "foo_meta" which returns a very simple descriptive data structure. Here is one that I wrote within the past month or two:

    sub __profile_meta { return { desc => 'Return an existing domain site profile', args => { domain => { desc => 'Domain for which to fetch the profile', required => 1, type => 'domain', }, file => { desc => 'Optional - The file location' .' where this profile is installed.' .' Defaults to profile.html", required => 0, }, }, result => { file => 'The file that this profile' .' will be installed at", body_logo => "Logo for the page", body_sections => [{ type => 'Type of content', html => 'The content itself', }], body_slogan => "Slogan for the page", contacts => [{ name => "Name for this contact", email => "Email for the contact", }], meta_description => 'Meta tag description', meta_keywords => ['List of keywords'], }, }; }

    I've found that I can fit pretty much anything I need to into this scheme. Of course YMMV.

    my @a=qw(random brilliant braindead); print $a[rand(@a)];

      Thanks for your opinion on this - I'm a fan of rather simple things that over-enginered ones! The fact that there is no standard or default way to do this implies that the work needed to define, implement one is higher than just documenting and doing it the fast way - which is just fine!

      Thanks for the profile example - looks good, but probably lots of implementation needed when it comes to binding Java Services to it :)

        "but probably lots of implementation needed when it comes to binding Java Services to it

        Possibly true.

        My consumers have typically been perl, javascript, php, or python - all dynamic folk. Yes - potentially there could be a little more work for those using Java, but I don't really think there would be that much more. In actuality I doubt any existing JSON service would be much easier to bind to Java. Unless you are using a WSDL I doubt there are many (if any) JSON web service libraries that would do the automatic type conversions that you get with WSDL.

        Either way, Java will likely have top-notch JSON classes - and if they do then constructing an appropriate JSON message would not be difficult, nor would getting information out of a JSON response and type casting. Ultimately that isn't really that more work than fiddling with WDSLs and having to pull information out of the automatically parsed structure returned by the SOAP libraries. The real time it is faster and easier with SOAP is when you are passing struct type objects and consuming those objects on the client end - very little of my work has ever wanted to deal with information in that form.

        my @a=qw(random brilliant braindead); print $a[rand(@a)];
Re: JSON WebService Description with PERl
by tobyink (Canon) on May 08, 2012 at 14:34 UTC

    FYI, I maintain a Perl json-schema implementation. It's on CPAN as JSON::Schema and is fairly interoperable with the Javascript reference implementation.

    Yes, json-schema is still a draft and it's lost some of the momentum it once had, but it is still progressing, albeit slowly.

    JSON-Service is itself based on json-schema.

    JSON::Schema does not support the CLI-generation feature you describe, and I can't see how it could, as json-schema doesn't do web service descriptions. It describes data structures, enabling them to be validated, and not much more.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
      iirc. which is where JSON-Service is going to have JSD (JSON Service Description) in order to generate clients from?
Re: JSON WebService Description with PERl
by sundialsvc4 (Abbot) on May 08, 2012 at 12:50 UTC

    My immediate inquiry is ... when you say that the service is “implemented in Mojolicious,” can you please describe (don’t just post a listing!) what the present program consists of?   Did they create some kind of unfinished schema document, “just for show?”  Where is this project coming from, so to speak, and where does it need to go?

      The current programm consists of CRUD REST operations for different resources.

      1: But in order to have these Operations or Calls documented in whatever wiki (current state) we would like to have some kind of a META Call which generates a service description for the current instance. The service documents itself

      2: It would be nice to have a client-side which generates a dynamic CLI from the above fetched service description

        Here is an idea, if you've got a model, you can write a generator, see UML to Perl

        Say you created models using Moose (or one of the alternatives) and they use MooseX::Params::Validate ... and now you're providing a RESTful interface to these classes.

        Well, grab UML::Class::Simple and generate some uml, then you feed said uml through ummf to generate whatever you're after, a Joose based validator and jQuery interface to your RESTful api, a perl interface to your RESTful api ...

        But IMHO, JSON really doesn't need a web service description language other than english

        It turns out JSON-RPC-1.1 is contemptible :)

Re: JSON WebService Description with PERl
by Anonymous Monk on May 08, 2012 at 12:53 UTC

      Well, WADL is not-a-standard and its not JSON, it makes little sense to describe a RESTful JSON service using XML -- the point of JSON was to avoid XML

        right, WADL is just overkill, again - not practicable, except if you are looking for sth to do and not to achieve sth</p

Re: JSON WebService Description with PERl
by sundialsvc4 (Abbot) on May 09, 2012 at 02:25 UTC

    On a complete aside ... I have been very pleased with RPC::Any as a basic framework for a recent project.   (It is not an exact fit to this requirement, but a very fine framework for RPC.   Just sayin’ FYI.)

    Edit:   I have also learned to add the following features, as part of the descriptive information that goes back and forth (if it’s not already provided by the protocol):

    1. A version-number.   If the format changes, change the number.   You never know when an old version of something is still out there wanting to talk to you.
    2. A randomly generated string, produced by the client, which the host must return verbatim.   Excellent for matching up requests with responses.   (But don’t be tempted to use it as a reliable-identifier on the host-side.)