Your best bet for making HTTP calls is thru curl.
This code assumes you're interacting with a JSON-based API. We use dkjson here because it's pure-lua, which eases distribution.
(include :cURL.impl.cURL) ; only necessary for standalone builds
(local curl (require :cURL))
(local json (require :dkjson))
(fn request [url]
(let [out []]
(with-open [h (curl.easy {:url url
:httpheader ["User-Agent: Fennel example"]
:writefunction {:write #(table.insert out $2)}})]
(h:perform))
(json.decode (table.concat out "\n"))))
(match arg
[url] (print (request url))
_ (print "Gimme a URL!"))
Building an executable is a little more complicated when you have a C
library as a dependency, but luckily in this case it is not too bad
with the --compile-binary
and --native-module
Fennel options.
Add Lua-cURLv3 and Lua into your repository with subtrees or submodules. This makefile assumes you have a copy of the Fennel compiler included in your repo as well, which is a good idea for repeatability reasons.
STATIC_LUA_LIB=lua/liblua.a
LUA_INCLUDE_DIR=lua/
LUA_PATH="?.lua;Lua-cURLv3/src/lua/?.lua"
http-bin: http.fnl Lua-cURLv3/lcurl.a $(STATIC_LUA_LIB)
CC_OPTS="-lcurl" LUA_PATH=$(LUA_PATH) ./fennel --compile-binary $< $@ \
$(STATIC_LUA_LIB) $(LUA_INCLUDE_DIR) \
--native-module Lua-cURLv3/lcurl.a
chmod 755 $@
lua/lua.h:
git submodule init
git submodule update
$(STATIC_LUA_LIB): lua/lua.h
make -C lua/ liblua.a
Lua-cURLv3/lcurl.a: lua/lua.h
make -C Lua-cURLv3/ lcurl.a LUA_IMPL=5.3 LUA_INC=$(PWD)/$(LUA_INCLUDE_DIR)
clean:
rm -rf http-bin $(STATIC_LUA_LIB) # make clean inside lua/ is weeeeeird
make -C Lua-cURLv3/ clean
.PHONY: clean
The http-bin
executable produced will run on any system that has
Curl installed, but it does not need to have Lua, Fennel, or the
Lua-curl bindings.
For a complete example see the fennel-http-example repo.