Moonwalk
Moonwalk is a Swagger server implementation for Lua.
Warning: This project is under heavy development. The Moonwalk API is not stable. Moonwalk itself is not stable. Don't use this in production (yet).
Moonwalk is designed to work under various host environments. Currently Moonwalk supports CGI, Mongoose, Civetweb, and LuaNode, as well as a built-in testing server, "SocketServer". Support can easily be added for other host environments.
This document should cover most of what you need to get started. For more advanced topics, see the generated documentation .
Installing
To get started with Moonwalk, you can clone this git repository, which includes Moonwalk, the API Explorer, example code, and documentation.
git clone https://github.com/abadc0de/moonwalk.git
luarocks install moonwalk --from=moonwalk/rocks
If you don't need the API Explorer or any examples, you can install Moonwalk without cloning the repository:
luarocks install moonwalk --from=http://abadc0de.github.io/moonwalk/rocks
Overview
Index page
Your API's index page should something like this:
-- index.lua -- 1: Load Moonwalk local api = require 'moonwalk/api' -- 2: Register APIs api:load_class 'user' api:load_class 'widget' api:load_class 'gadget' -- 3: Handle request api:handle_request(...)
1. Require Moonwalk and assign it to a local variable.
Call api:load_class once for each API class (see below).
Call api:handle_request .
Make sure to pass the ellipses (varargs) as shown.
Documenting your API
Functions in your API should be decorated with doc blocks.
Valid tags include @path
, @param
, and @return
.
Here's a quick example of a complete API with a single operation:
user.lua
--- User API return { --- Create a new user. -- -- @path POST /user/ -- -- @param email: User's email address. -- @param password: User's new password. -- @param phone (optional): User's phone number. -- -- @return (number): User's ID number. -- create = function(email, password, phone) return 123 end, }
Moonwalk parses the docstring to determine the request method, resource path, and parameters for the function.
The @path tag
The @path
tag is used to provide the HTTP request method and resource
path for the operation. "Path parameters" may be included as part of the
path, by enclosing the parameter name in braces. For example:
@path GET /widget/{id}/
The @param tag
The @param
tag may contain additional information, enclosed in
parentheses, after the parameter name. This can include the
data type, the word "from" followed by the param type,
optionally separated by punctuation. It may also include punctuation
after the parentheses to visually separate the description. For example:
@param id (integer, from path): The ID of the widget to fetch.
The @return tag
The @return
tag may contain a data type annotation, enclosed in
parentheses, before the description, optionally followed by
punctuation. For example:
@return (integer): The ID of the newly-created widget.
Validation
In @param
and @return
tags, any data type name may be used,
but built-in type checking is only provided for the following:
integer
, number
, string , boolean
, object
, array
In @param
tags, the param type determines how information is
sent to the API. Valid values are:
path
, query
, body
, header
, form
If the data type annotation is present, it must be listed first. All other parenthesized annotations may be listed in any order. Any annotation may be omitted, in which case the default values will be used. If all annotations within the parentheses are omitted, the parentheses may also be omitted.
The default data type is string , and the default param type is determined as follows:
If the parameter name appears in curly brackets in the
@path
,the default param type is
path
.If the HTTP method is
POST
, the default param type isform
.In all other cases, the default param type is
query
.
In addition to a data type and param type, the @param
tag may
include additional validation annotations within the parentheses following
the parameter name. Recognized annotations draw from the JSON Schema
validation specification.
Validation for all types
These validation annotations are available for any parameter.
- optional
By default, all parameters are required. To make a parameter optional,
use the optional
annotation.
Numeric validation
These validation annotations are available for
number
and integer
parameters.
- maximum (partly implemented)
Numeric parameters may enforce a maximum value using the annotationmaximum N [exclusive]
, where *N* is any valid number, optionally followed byexclusive
to indicate that the value must be less than (but not equal to) *N*.
* minimum (partly implemented)
Numeric parameters may enforce a minimum value using the annotationminimum N [exclusive]
, where *N* is any valid number, optionally followed byexclusive
to indicate that the value must be greater than (but not equal to) *N*.
* multipleOf
Numeric parameters may limit a value to being evenly divisible
by a number using the annotation multipleOf N
,
where *N* is any valid number greater than 0.
String validation
These validation annotations are available forstring parameters.
- maxLength
String parameters may enforce a maximum length using the
annotation maxLength N
, where *N* is any valid
non-negative integer.
* minLength
String parameters may enforce a minimum length using the
annotation minLength N
, where *N* is any valid
non-negative integer.
* pattern (not yet implemented)
String parameters may be checked against a regular expression
using the annotation pattern P
, where *P* is any
valid regular expression, enclosed in backticks.
Array validation
These validation annotations are available for array
parameters.
- maxItems
Array parameters may enforce a maximum length using the
annotation maxItems N
, where *N* is any valid
non-negative integer.
* minItems
Array parameters may enforce a minimum length using the
annotation minItems N
, where *N* is any valid
non-negative integer.
* uniqueItems
Array parameters may ensure that every item in the array
is unique using the uniqueItems
annotation.
Models
Models are a useful way to document how an object should look. Currently no built-in validation is provided for models, but some Swagger clients may use this information to provide client side validation or documentation. They also show up in the API Explorer.
You can define models like this:
local api = require "moonwalk/api" api.model "User" { id = { type = "integer", minimum = 1, description = "The user's ID number" }, email = { description = "The user's email address" }, name = { optional = true, description = "The user's full name" }, phone = { type = "integer", optional = true, description = "The user's phone number", }, }
This is essentially the properties
object in a Swagger models
section. You can use the model name as a data type in your
@param
and @return
tags, and in other models. You can also use
full Swagger-style model definitions. Models defined using the short
syntax above will be converted to full definitions by .model
.
See Swagger's Complex Types for more information.
Host environments
Some host environments (SocketServer, LuaNode) use one Lua state across multiple requests, while others (CGI, Mongoose, Civetweb) handle each request in a separate Lua state. We'll call the first category "persistent hosts" and the second "traditional hosts."
SocketServer
Invoke the built-in Lua server like this:
lua moonwalk/server/socket.lua /example/ 8910
Where /example/
is your API root and 8910
is the port to use.
LuaNode
Experimental support for LuaNode is included. Invoke the server like this:
/path/to/luanode moonwalk/server/luanode.lua /example/ 8910
Where /example/
is your API root and 8910
is the port to use.
Mongoose/Civetweb
Mongoose/Civetweb support is included. Invoke the server like this:
/path/to/server/binary \ -document_root /srv/www/moonwalk/ \ -url_rewrite_patterns /example/**=example/index.lp
Apache CGI Setup
Use this Apache vhost configuration and .htaccess file as an example.
Apache vhost config
<VirtualHost *:80> ServerName moonwalk.local DocumentRoot /srv/www/moonwalk <Directory /srv/www/moonwalk> Options +ExecCGI AddHandler cgi-script .lua DirectoryIndex index.lua index.html AllowOverride All Order allow,deny allow from all </Directory> </VirtualHost>
Apache .htaccess
RewriteEngine On RewriteCond $1 !(^index\.lua) RewriteRule ^(.*)$ index.lua/$1 [L]
CGI troubleshooting
- Make sure the shebang line has the correct path to the Lua executable.
For example,
#! /usr/bin/lua
may need to become#! /usr/local/bin/lua
. - Make sure any files with the shebang are executable (chmod +x).
License
Copyright © 2013 Moonwalk Authors
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
References
Lua references:
Swagger references:
CGI references:
Mongoose and Civetweb references: