86 lines
2.7 KiB
Nim
86 lines
2.7 KiB
Nim
#
|
|
# REST API framework implementation
|
|
# (c) Copyright 2021-Present
|
|
# Status Research & Development GmbH
|
|
#
|
|
# Licensed under either of
|
|
# Apache License, version 2.0, (LICENSE-APACHEv2)
|
|
# MIT license (LICENSE-MIT)
|
|
import chronos/apps
|
|
import stew/[results, byteutils]
|
|
export results, apps
|
|
|
|
{.push raises: [Defect].}
|
|
|
|
type
|
|
ContentBody* = object
|
|
contentType*: string
|
|
data*: seq[byte]
|
|
|
|
RestResult*[T] = Result[T, cstring]
|
|
|
|
RestApiError* = object
|
|
status*: HttpCode
|
|
message*: string
|
|
contentType*: string
|
|
|
|
RestApiResponseKind* {.pure.} = enum
|
|
Empty, Error, Redirect, Content
|
|
|
|
RestApiResponse* = object
|
|
status*: HttpCode
|
|
case kind*: RestApiResponseKind
|
|
of RestApiResponseKind.Empty:
|
|
discard
|
|
of RestApiResponseKind.Content:
|
|
content*: ContentBody
|
|
of RestApiResponseKind.Error:
|
|
errobj*: RestApiError
|
|
of RestApiResponseKind.Redirect:
|
|
location*: string
|
|
preserveQuery*: bool
|
|
|
|
ByteChar* = string | seq[byte]
|
|
|
|
RestDefect* = object of Defect
|
|
RestError* = object of CatchableError
|
|
RestBadRequestError* = object of RestError
|
|
RestEncodingError* = object of RestError
|
|
field*: cstring
|
|
RestDecodingError* = object of RestError
|
|
RestCommunicationError* = object of RestError
|
|
exc*: ref CatchableError
|
|
RestRedirectionError* = object of RestError
|
|
RestResponseError* = object of RestError
|
|
status*: int
|
|
contentType*: string
|
|
message*: string
|
|
|
|
proc error*(t: typedesc[RestApiResponse],
|
|
status: HttpCode = Http200, msg: string = "",
|
|
contentType: string = "text/html"): RestApiResponse =
|
|
RestApiResponse(kind: RestApiResponseKind.Error, status: status,
|
|
errobj: RestApiError(status: status, message: msg,
|
|
contentType: contentType))
|
|
|
|
proc response*(t: typedesc[RestApiResponse], data: ByteChar,
|
|
status: HttpCode = Http200,
|
|
contentType = "text/text"): RestApiResponse =
|
|
let content =
|
|
when data is seq[byte]:
|
|
ContentBody(contentType: contentType, data: data)
|
|
else:
|
|
block:
|
|
var default: seq[byte]
|
|
if len(data) > 0:
|
|
ContentBody(contentType: contentType, data: toBytes(data))
|
|
else:
|
|
ContentBody(contentType: contentType, data: default)
|
|
RestApiResponse(kind: RestApiResponseKind.Content, status: status,
|
|
content: content)
|
|
|
|
proc redirect*(t: typedesc[RestApiResponse], status: HttpCode = Http307,
|
|
location: string, preserveQuery = false): RestApiResponse =
|
|
RestApiResponse(kind: RestApiResponseKind.Redirect, status: status,
|
|
location: location, preserveQuery: preserveQuery)
|