Monday, July 14, 2014

Parsing RAML with FParsec, Part 1: Background and Goals


Hi everyone, and welcome to what I hope will be an exciting journey into the world of parsers and combinators.  

Yeah, those words terrify me too.

I had this crazy idea one day at work that it would be fantastic if I had some better tooling around our internal representation of a particular REST service.  In general, these things are planned out ahead of time and contracts are negotiated, but even in the best of times some details can be left out and consistency in you API can be something that's hard to quantify.

So I went and did an initial search to see what the tooling was like and stumbled across, the landing page of the RESTful API Modeling Language.  This seemed like a wonderful tool, with a spec that seemed well-geared towards encouraging API consistency by use of common traits and security schemes.  It also has visualizers and tooling around code generation, which can help reduce the time it takes to crank out the internals of your API.  Anyway, check out RAML or any of its competitors if you're designing an API.

Now, work is mostly .Net languages, and most(all?) of the existing RAML tools are in more...dynamic languages.  I thought it would be really helpful to have some sort of automated converter for .Net that would allow you to populate a structure with your API setup and generate a RAML-compliant description, at which point you could plug that into existing tooling, make changes, and design new APIs.  You could also use this model to do code generation, analysis, etc.

So at this point the delusions of grandeur started to flow, and I thought "If I have a parser, I could totally generate a F# Type Provider using the RAML as the data source to allow for easy exploration and consumption of that API."

And then "If I have an explorable, strongly-typed representation of a REST endpoint, there are F# libraries for generating comprehensive test cases for various inputs, so I MIGHT even be able to exhaustively test a subset of RAML-compliant REST services AUTOMATICALLY!"

But all of these cases require the parser, and so I began to look at what tools I had available.  F#, and functional languages in general, have developed a reputation for being good at parsing text into data.  In addition, I'd developed a fancy for the language after working with the magnificent, cross-platform build tool FAKE.  So it was that I stumbled upon FParsec, and so begins this series of blog posts.

So, to summarize, I hope to use FParsec and the RAML spec to:
  1. Generate a .Net native parser for the RAML spec that outputs a .Net type representing a REST endpoint and its constraints, methods, etc
  2. Generate a Type Provider that you can direct at a RAML spec, either a URI or a local file, and use to explore that API at design time, and (stretch goal)
  3. Develop a tool that, given an endpoint with sufficient constraints around the inputs and outputs of its routes, can be tested in some degree automatically for compliance to a matching RAML spec.
The next post should follow shortly, and we'll start with the basics of parsing using FParsec.  Do note that I'm still quite new to this, so please join in with any comments or suggestions!