Skip to content
Phil Hagelberg edited this page Apr 23, 2023 · 3 revisions

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.

Clone this wiki locally