{"id":13811487,"url":"https://github.com/janet-lang/circlet","last_synced_at":"2025-10-17T13:01:48.521Z","repository":{"id":47020268,"uuid":"148086924","full_name":"janet-lang/circlet","owner":"janet-lang","description":"HTTP server library for janet","archived":false,"fork":false,"pushed_at":"2021-09-16T22:47:26.000Z","size":534,"stargazers_count":78,"open_issues_count":3,"forks_count":10,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-08-04T04:01:08.735Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","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/janet-lang.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":"2018-09-10T02:17:42.000Z","updated_at":"2024-07-28T22:09:53.000Z","dependencies_parsed_at":"2022-09-18T05:00:35.273Z","dependency_job_id":null,"html_url":"https://github.com/janet-lang/circlet","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/janet-lang%2Fcirclet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janet-lang%2Fcirclet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janet-lang%2Fcirclet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janet-lang%2Fcirclet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/janet-lang","download_url":"https://codeload.github.com/janet-lang/circlet/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224008008,"owners_count":17240293,"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":[],"created_at":"2024-08-04T04:00:22.021Z","updated_at":"2025-10-17T13:01:48.448Z","avatar_url":"https://github.com/janet-lang.png","language":"C","funding_links":[],"categories":["C","Web"],"sub_categories":["Server"],"readme":"# Circlet\n\nCirclet is an HTTP and networking library for the\n[janet](https://github.com/janet-lang/janet) language.\nIt provides an abstraction out of the box like Clojure's\n[ring](https://github.com/ring-clojure/ring), which is a server abstraction\nthat makes it easy to build composable web applications.\n\nCirclet uses [mongoose](https://cesanta.com/) as the underlying HTTP server\nengine. Mongoose is a portable, low footprint, event based server library. The\nflexible build system requirements of mongoose make it very easy to embed\nin other C programs and libraries.\n\n## Installing\n\nYou can add Circlet as a dependency in your `project.janet`:\n\n```clojure\n(declare-project\n  :name \"web framework\" :description \"A framework for web development\"\n  :dependencies [\"https://github.com/janet-lang/circlet.git\"])\n```\n\nYou can also install it system-wide with `jpm`:\n\n```\nsh jpm install circlet\n```\n\n## Usage\n\n### Creating a server\n\nYou can create a HTTP server using the `circlet/server` function. The\nfunction is of the form `(circlet/server handler port \u0026opt ip-address)`\nand takes the following parameters:\n\n- `handler` function that takes the incoming HTTP request object (explained in\n    greater detail below) and returns the HTTP response object.\n- `port` number of the port on which the server will listen for incoming\n    requests.\n- `ip-address` optional string representing the IP address on which the server\n    will listen (defaults to `“127.0.0.1”`). The address `“*”` will\n    cause the server to listen on all available IP addresses.\n\nThe server runs immediately after creation.\n\n### Request\n\nThe `handler` function takes a single parameter representing the request. The\nrequest is a Janet table containing all the information about the request. It\ncontains the following keys:\n\n- `:uri` requested URI\n- `:method` HTTP method of the request as a Janet string (e.g. \"GET\", \"POST\")\n- `:protocol` version of the HTTP protocol used for request\n- `:headers` HTTP headers sent with the request as a Janet table. Keys in this\n    table are Janet strings with standard header's name (e.g. \"Host\", “Accept\").\n    Values are the values in the HTTP header.\n- `:body` body of the HTTP request\n- `:query-string` query string part of the requested URI\n- `:connection` internal mongoose connection serving this request\n\n### Response\n\nThe return value of the `handler` function must be a Janet table containing\nat least the `status` key with an integer value that corresponds to the HTTP\nstatus of the response (e.g. 200 for success).\n\nOther possible keys include:\n\n- `:body` the body of the HTTP response (e.g. a string in HTML or JSON)\n- `:headers` a Janet table or struct with standard HTTP headers. The structure\n    is the same as the HTTP request case described above.\n\nThere is also special key `:kind` you can use. There are two possible values for\nthis key:\n\n- `:file` for serving a file from the filesystem. The filename is specified by\n    the `:file` key. You can specify `:mime` key with value of corresponding\n    mime type, it defaults to text/html.\n- `:static` for serving static file from the filesystem. You have to provide\n    `:root` key with value of the path you want to serve.\n\n### Middleware\n\nCirclet also allows for the creation of different “middleware”. Pieces\nof middleware can be thought of as links in a chain of functions that are\nused to consume the HTTP request. The `handler` function can be thought of\nas a piece of middleware and other middleware should match the signature and\nreturn type of the `handler` function, i.e. accept and return a Janet table.\n\nMiddleware can be created in one of two ways. A user can define a function\nwith the appropriate signature and return type or use Circlet’s\n`circlet/middleware` function to coerce an argument into a piece of\nmiddleware. Middleware pieces are often higher-order functions (meaning\nthat they return another function). This allows for parameterization at\ncreation time.\n\n#### Provided middleware\n\nThere are three basic pieces of middleware provided by Circlet:\n\n- `(circlet/router routes)` simple routing facility. This function takes a\n    Janet table containing the routes. Each key should be a Janet string matching\n    a URI (e.g. `”/“`, `”/posts\"`) with a value that is a function of the\n    same form as the `handler` function described above.\n- `(circlet/logger nextmw)` simple logging facility. This function prints\n    the request info on `stdout`. The only argument is the next middleware.\n- `(circlet/cookies nextmw)` middleware which extracts the cookies from the\n    HTTP header and stores the value under the `:cookies` key in the request\n    object.\n\n## Example\n\nThe below example starts a very simple web server on port 8000.\n\n```clojure\n(import circlet)\n\n(defn myserver\n \"A simple HTTP server\" [request]\n {:status 200\n  :headers {\"Content-Type\" \"text/html\"} :body \"\u003c!doctype html\u003e\u003chtml\u003e\u003cbody\u003e\u003ch1\u003eHello.\u003c/h1\u003e\u003c/body\u003e\u003c/html\u003e\"})\n\n(circlet/server myserver 8000)\n```\n\n## Development\n\n### Building\n\nBuilding requires [Janet](https://github.com/janet-lang/janet) to be installed\non the system, as well as the `jpm` tool (installed by default with Janet).\n\n```sh\njpm build\n```\n\nYou can also just run `jpm` to see a list of possible build commands.\n\n### Testing\n\nRun a server on localhost with the following command\n\n```sh\njpm test\n```\n\nThis example is more involved, and shows all the functionality described in this\ndocument.\n\n## License\n\nUnlike [janet](https://github.com/janet-lang/janet), Circlet is licensed\nunder the GPL license in accordance with mongoose.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjanet-lang%2Fcirclet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjanet-lang%2Fcirclet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjanet-lang%2Fcirclet/lists"}