{"id":13636072,"url":"https://github.com/losinggeneration/gimlet","last_synced_at":"2025-08-12T18:44:53.608Z","repository":{"id":16499186,"uuid":"19251996","full_name":"losinggeneration/gimlet","owner":"losinggeneration","description":"A micro web application framework for OpenResty written in Moonscript inspired by Martini \u0026 Sinatra.","archived":false,"fork":false,"pushed_at":"2017-03-23T23:49:09.000Z","size":499,"stargazers_count":27,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-15T01:54:14.858Z","etag":null,"topics":["gimlet","lua","micro-framework","microservice","moonscript","rest-api","sinatra","xavante"],"latest_commit_sha":null,"homepage":null,"language":"MoonScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/losinggeneration.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-04-28T20:00:52.000Z","updated_at":"2024-09-09T19:16:15.000Z","dependencies_parsed_at":"2022-09-13T22:42:58.357Z","dependency_job_id":null,"html_url":"https://github.com/losinggeneration/gimlet","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/losinggeneration%2Fgimlet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/losinggeneration%2Fgimlet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/losinggeneration%2Fgimlet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/losinggeneration%2Fgimlet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/losinggeneration","download_url":"https://codeload.github.com/losinggeneration/gimlet/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248991540,"owners_count":21194894,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gimlet","lua","micro-framework","microservice","moonscript","rest-api","sinatra","xavante"],"created_at":"2024-08-02T00:00:56.609Z","updated_at":"2025-04-15T01:54:21.530Z","avatar_url":"https://github.com/losinggeneration.png","language":"MoonScript","readme":"# Gimlet Cocktail\nversion **0.1.1-dev**\n\nGimlet Cocktail is a micro web application framework for [OpenResty](http://openresty.org/)[[2](#getting-started-note-2)] written in [Moonscript](http://moonscript.org/). The hope is that it's useful, modular, and makes writing web applications (especially RESTful ones) quick and fun.\n\n## Getting started\n\n* First thing to do is to install Moonscript [[1](#getting-started-note-1)]\n* To use the command line tool, you'll need a couple more dependencies:\n  * lua_cliargs \u003e= 2.1 - For command line argument parsing.\n  * luafilesystem \u003e= 1.5 - For ensuring the web server is running from the correct location.\n* Then you should make sure to either have OpenResty installed\n* (Alternatively) Install wsapi, wsapi-xavante, \u0026 xavante.\n\n* Create a file named app.moon with the following code:\n```moonscript\nimport get, run from require 'gimlet.classic'\n\nget '/', -\u003e\n  'Hello world!'\n\nrun!\n```\n* Now you can compile the code with ```moonc app.moon```\n* You can run use the gimlet command to start the server ```gimlet app``` [[2](#getting-started-note-2)]\n\nYou will now have a Gimlet application running on your web server of choice on ```http://localhost:8080```\n\n[\u003ca name=\"getting-started-note-1\"\u003e1\u003c/a\u003e] All dependencies can be installed via LuaRocks.\n\n[\u003ca name=\"getting-started-note-2\"\u003e2\u003c/a\u003e] The default is use use OpenResty. [Xavante](http://keplerproject.github.io/xavante) can be used by using ```gimlet -x app```\n\n## Table of Contents\n* [Classic Gimlet](#classic-gimlet)\n  * [Handlers](#handlers)\n  * [Routing](#routing)\n  * [Services](#services)\n  * [Serving Static Files](#serving-static-files)\n* [Middleware Handlers](#middleware-handlers)\n  * [Middleware Yielding](#middleware-yielding)\n* [Available Middleware](#available-middleware)\n* [Code Reloading](#code-reloading)\n* [Using Lua](#using-lua)\n\n## Classic Gimlet\n ```gimlet.classic``` tries to provide reasonable defaults for most web applications. The general pieces are requiring ```gimlet.classic```, setting up any additional middleware, adding items to be passed to the routes, setting up your routing information, and running the application.\n```moonscript\n-- Pull in the Classic Gimlet\nclassic = require 'gimlet.classic'\n\n-- Optionally define a variable to be available to all requests\nclassic.map \"world\", 'World'\n\n-- Define a middleware to use\nclassic.use (require 'gimlet.render').Render!\n\n-- Define a route '/' with params\nclassic.get '/', (params) -\u003e\n  params.render.json hello: params.world\n\n-- Run the Gimlet application\nclassic.run!\n```\n\n### Handlers\nHandlers are how you get things done in Gimlet (as they are in Martini.) A handler is a any callable function.\n```moonscript\nclassic.get '/', -\u003e\n  print \"hello world\"\n```\n\n#### Return Values\nHandlers can return a string value and that will be sent back as a simple HTTP HTML response.\n```moonscript\nclassic.get '/', -\u003e\n  \"hello world\" -- HTTP 200 : \"hello world\"\n```\nIf the first option is numeric, it changes the HTTP response code.\n```moonscript\nclassic.get '/', -\u003e\n  418, \"i'm a teapot\" -- HTTP 418 : \"i'm a teapot\"\n```\n\nIf the first option is a table, other things about the HTTP response can be changed, such as Content-Type, headers, and the status.\n```moonscript\nclassic.get '/', -\u003e\n  'Content-Type': 'application/json', status: 401, [[{\"error\": \"you're not authorized to access content\"}]]\n```\n\n#### Parameters\nThe handlers can optionally take a single table parameter.\n```moonscript\nclassic.get '/', (p) -\u003e\n  p.utils.now!\n```\nThe following are mapped to the table by default:\n* gimlet - An instance of the Gimlet class\n* request - An instance of the HTTP request object\n* response - An instance of the HTTP response object.\n* utils - An instance of some utility functions\n\nIn addition to these, route globs and named parameters are mapped to the parameter as well. See [Routing](#routing) for more information on this.\n\n### Routing\nIn Gimlet, a route is an HTTP method paired with a URL-matching pattern. Each route can take one or more handler methods:\n```moonscript\nclassic.get '/', -\u003e\n  -- show something\n\nclassic.patch '/', -\u003e\n  -- update something\n\nclassic.post '/', -\u003e\n  -- create something\n\nclassic.put '/', -\u003e\n  -- replace something\n\nclassic.delete '/', -\u003e\n  -- destroy something\n\nclassic.options '/', -\u003e\n  -- http options\n\nclassic.not_found -\u003e\n  -- handle 404\n```\n\nRoutes are matched in the order they are defined. The first route that matches the request is invoked.\n\nRoute patterns may include named parameters:\n```moonscript\nclassic.get '/:name', (p) -\u003e\n  'hello ' .. p.params.name\n```\n\nRoutes can be matched with globs:\n```moonscript\nclassic.get '/**', (p) -\u003e\n  'hello ' .. p.params[1]\n```\nRoute groups can be added too using the group method:\n```moonscript\nclassic.group '/books', (r) -\u003e\n  r\\get '', get_books\n  r\\get '/:id', get_book\n  r\\post '/new', new_book\n  r\\put '/update/:id', update_book\n  r\\delete '/delete/:id', delete_book\n```\n### Services\nServices are objects that are available to be injected into a handler's parameters table.\n\n```moonscript\ndb = my_database!\nclassic.map \"db\", db -- the service will be available to all handlers as -\u003e (p) p.db\n-- Alternative\nclassic.map :db -- Same as above, but you can pass a table with a single {k: v} into map\n-- ...\nclassic.run!\n```\n\n### Serving Static Files\n```gimlet.classic``` automatically serves files from ```public``` relative to the main module.\nYou can add additional directories to serve as well:\n```moonscript\nimport Static from require 'gimlet.static'\nclassic.use Static '/css'\n```\nNote the '/' at the beginning is needed to path match the url. This may change in the future.\nIf you plan on serving images from this middleware, you should install ```mimetypes```\n\nAlternatively, you can let the HTTP server handle static files with ```gimlet -s static_dir app```\n\n## Middleware Handlers\nMiddlware handlers sit between the incoming http request and the router. They are, in essence, no different than any other handler in Gimlet. You can add a middleware handler to the stack with:\n```moonscript\nclassic.use -\u003e\n  -- do middleware stuff\n```\n\nYou also have full control over the middleware stack with the ```Gimlet\\handlers``` function. This will replace all handlers that were previously set:\n```moonscript\nclassic.handlers middleware1, middleware2, middleware3\n```\n\nMiddleware handlers tend to work well for things like: logging, authorization, authentication, sessions, errors, or anything else that needs to happen before and/or after an HTTP request.\n\n### Middleware Yielding\nDuring a middleware handler call, the middleware can optionally call ```coroutine.yield```. This allows somet things to happen before and after the request.\n```moonscript\nclassic.use -\u003e\n  print \"before a request\"\n\n  coroutine.yield!\n\n  print \"after a request\"\n```\n\n## Available Middleware\n* [Render](http://github.com/losinggeneration/gimlet-render) - Handles rendering JSON \u0026 HTML templates.\n\n## Code Reloading\nCode reloading is accomplished by using ```gimlet -r``` It works well with OpenResty. However, Xavante seems to have some issues currently.\n\n## Using Lua\nUp until this point, Moonscript has been assumed for everything. There's support for using Lua; however, this isn't well tested.\n```lua\nlocal classic = require 'gimlet.classic'\n\nclassic.get('/', function()\n        return 'Hello world!'\nend)\n\nclassic.run()\n```\n\n## About\nGimlet Cocktail is inspired by projcets like [Martini](http://github.com/go-martini/martini) and [Sinatra](https://github.com/sinatra/sinatra). Some code is heavily based off Martini as well.\n\n","funding_links":[],"categories":["Libraries"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flosinggeneration%2Fgimlet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flosinggeneration%2Fgimlet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flosinggeneration%2Fgimlet/lists"}