HTTP handling framework


_ <- fat.http


A route is a structure used to map HTTP methods to certain path patterns, specifying what code should be executed when a request comes in. Each route can define a different behavior for each HTTP method (POST, GET, PUT, DELETE).


Name Signature Brief
Route (path: Text, post: Method, get: Method, put: Method, delete: Method) Constructs a Route object

each implemented method receives an HttpRequest as argument and shall return an HttpResponse object


An HttpRequest represents an HTTP request message. This is what your server receives from a client when it makes a request to your server.


Name Signature Brief
HttpRequest (method: Text, path: Text, params: Scope, headers: List/Text, body: Any) Constructs an HttpRequest object


An HttpResponse represents an HTTP response message. This is what a server sends back to the client in response to an HTTP request.


Name Signature Brief
HttpResponse (status: Number, headers: List/Text, body: Any) Constructs an HttpResponse object


Name Signature Brief
setHeaders (headers: List): Void Set headers of requests
post (url: Text, body, wait): HttpResponse Create/post body to url
get (url: Text, wait): HttpResponse Read/get from url
put (url: Text, body, wait): HttpResponse Update/put body to url
delete (url: Text, wait): HttpResponse Delete on url
setName (name: Text): Void Set user agent/server name
verifySSL (enabled: Boolean): Void SSL configuration (client mode)
setSSL (certPath: Text, keyPath: Text): Void SSL configuration (server mode)
listen (port: Number, routes: List/Route) Endpoint provider (server mode)

body: Any and wait: Number are always optional parameters, being that if body does not fall under Text or Chunk, it will be automatically converted to JSON during the send process, and wait is the maximum waiting time and the default is 30,000ms (30 seconds)

verifySSL is enabled by default for the client mode

setSSL may not be available, case the system doesn't have OpenSSL

Usage Notes

Client mode

In the HttpResponse.body, you may need to explicitly parse a JSON response to Scope using the fromJSON method. To post a native type as JSON, you can encode it using the toJSON method; however, this is not strictly necessary, as it will be done implicitly. Both methods are available in the fat.recode library.

If headers are not set, the default Content-Type header for Chunk will be application/octet-stream, for Text will be text/plain; charset=UTF-8 and for other types, it will be application/json; charset=UTF-8 (due to implicit conversion).

You can set custom request headers like so:

http <- fat.http

url = ...
token = ...
body = ...

  "Accept: application/json; charset=UTF-8"
  "Content-Type: application/json; charset=UTF-8"
  "Authorization: Bearer " + token  # custom header
]), body)

setting headers will completely replace previous list with new list

When performing async requests, you may need to call setHeaders, setName, and configure verifySSL within each Worker, as these settings are local to each thread.

Server mode

Handling HTTP Responses

The FatScript server automatically handles common HTTP status codes such as 200, 400, 404, 405, 500, and 501. Being 200 the default when constructing an HttpResponse object.

In addition to the common status codes, you can also explicitly return other status codes, such as 201, 202, 203, 204, 205, 301, 401, and 403, by specifying the status code in the HttpResponse object, for example: HttpResponse(status = 401). In all cases, where applicable, the server provides default plain text bodies. However, you have the option to override these defaults and provide your own custom response bodies when necessary.

By automatically handling these status codes and providing default response bodies, the FatScript server simplifies the development process while still allowing you to have control over the response content when needed.

if the status code doesn't belong to any of the above, the server will return a 500 code

See an example of a simple file HTTP server:

_    <- fat.type.Text
file <- fat.file
http <- fat.http
{ Route, HttpRequest, HttpResponse } = http

# adapt to content location
basePath = '/home/user/contentFolder'

# restrict to some extensions only
getContentType = (path: Text): Text -> {
  ext2 = path(-3..).toLower
  ext3 = path(-4..).toLower
  ext4 = path(-5..).toLower

  ext4 == '.html' => 'Content-Type: text/html'
  ext3 == '.htm'  => 'Content-Type: text/html'
  ext2 == '.js'   => 'Content-Type: application/javascript'
  ext4 == '.json' => 'Content-Type: application/json'
  ext3 == '.css'  => 'Content-Type: text/css'
  ext2 == '.md'   => 'Content-Type: text/markdown'
  ext3 == '.xml'  => 'Content-Type: application/xml'
  ext3 == '.csv'  => 'Content-Type: text/csv'
  ext3 == '.txt'  => 'Content-Type: text/plain'
  ext4 == '.svg'  => 'Content-Type: image/svg+xml'
  ext3 == '.rss'  => 'Content-Type: application/rss+xml'
  ext4 == '.atom' => 'Content-Type: application/atom+xml'
  ext3 == '.png'  => 'Content-Type: image/png'
  ext3 == '.jpg'  => 'Content-Type: image/jpeg'
  ext4 == '.jpeg' => 'Content-Type: image/jpeg'
  ext3 == '.gif'  => 'Content-Type: image/gif'
  ext3 == '.ico'  => 'Content-Type: image/icon'

routes: List/Route = [
    get = (request: HttpRequest): HttpResponse -> {
      path = basePath + request.path
      type = getContentType(path)

      !type             => HttpResponse(status = 403)  # forbidden
      file.exists(path) => HttpResponse(body = file.readBin(path), headers = [ type ])
      _                 => HttpResponse(status = 404)  # not found

http.listen(8080, routes)

in a real application, request.path must be sanitized before being used to access files on the server; here, it is used directly only as an example

results matching ""

    No results matching ""