skir_client/service
Types
A controlled error that is sent back to the caller as a non-2xx HTTP response. Use this in your method implementations to signal expected failures (e.g. “not found”, “permission denied”).
pub type HttpErrorCode {
E400xBadRequest
E401xUnauthorized
E402xPaymentRequired
E403xForbidden
E404xNotFound
E405xMethodNotAllowed
E406xNotAcceptable
E407xProxyAuthenticationRequired
E408xRequestTimeout
E409xConflict
E410xGone
E411xLengthRequired
E412xPreconditionFailed
E413xContentTooLarge
E414xUriTooLong
E415xUnsupportedMediaType
E416xRangeNotSatisfiable
E417xExpectationFailed
E418xImATeapot
E421xMisdirectedRequest
E422xUnprocessableContent
E423xLocked
E424xFailedDependency
E425xTooEarly
E426xUpgradeRequired
E428xPreconditionRequired
E429xTooManyRequests
E431xRequestHeaderFieldsTooLarge
E451xUnavailableForLegalReasons
E500xInternalServerError
E501xNotImplemented
E502xBadGateway
E503xServiceUnavailable
E504xGatewayTimeout
E505xHttpVersionNotSupported
E506xVariantAlsoNegotiates
E507xInsufficientStorage
E508xLoopDetected
E510xNotExtended
E511xNetworkAuthenticationRequired
}
Constructors
-
E400xBadRequest -
E401xUnauthorized -
E402xPaymentRequired -
E403xForbidden -
E404xNotFound -
E405xMethodNotAllowed -
E406xNotAcceptable -
E407xProxyAuthenticationRequired -
E408xRequestTimeout -
E409xConflict -
E410xGone -
E411xLengthRequired -
E412xPreconditionFailed -
E413xContentTooLarge -
E414xUriTooLong -
E415xUnsupportedMediaType -
E416xRangeNotSatisfiable -
E417xExpectationFailed -
E418xImATeapot -
E421xMisdirectedRequest -
E422xUnprocessableContent -
E423xLocked -
E424xFailedDependency -
E425xTooEarly -
E426xUpgradeRequired -
E428xPreconditionRequired -
E429xTooManyRequests -
E431xRequestHeaderFieldsTooLarge -
E451xUnavailableForLegalReasons -
E500xInternalServerError -
E501xNotImplemented -
E502xBadGateway -
E503xServiceUnavailable -
E504xGatewayTimeout -
E505xHttpVersionNotSupported -
E506xVariantAlsoNegotiates -
E507xInsufficientStorage -
E508xLoopDetected -
E510xNotExtended -
E511xNetworkAuthenticationRequired
The return value of handle_request.
Write these fields directly to your HTTP framework response.
pub type RawResponse {
RawResponse(
status_code: Int,
content_type: String,
data: String,
)
}
Constructors
-
RawResponse(status_code: Int, content_type: String, data: String)
Dispatches RPC requests to registered methods.
Type parameters:
req_meta: per-request metadata supplied by your HTTP handlerstate: application statemessage: application state update, will be returned byhandle_request
Example setup:
service.new(empty_message: option.None)
|> service.add_method(user_out.get_user_method(), get_user)
|> service.add_method(user_out.add_user_method(), add_user)
|> service.set_keep_unrecognized_values(True)
|> service.set_can_send_unknown_error_message(fn(_info) { True })
pub opaque type Service(req_meta, state, message)
pub type ServiceError {
ServiceError(status: HttpErrorCode, message: String)
UnknownError(message: String)
}
Constructors
-
ServiceError(status: HttpErrorCode, message: String)A controlled error with an explicit HTTP status code and message. Use this to signal expected failures (e.g. not found, permission denied).
-
UnknownError(message: String)An unexpected internal error. The message is only forwarded to the client if can_send_unknown_error_message is enabled on the service.
Context passed to service hooks when a method returns an error.
pub type ServiceErrorInfo(req_meta, state) {
ErrorInfo(
error: ServiceError,
message: String,
method_name: String,
req_meta: req_meta,
state: state,
)
}
Constructors
-
ErrorInfo( error: ServiceError, message: String, method_name: String, req_meta: req_meta, state: state, )Arguments
- state
-
Application state
Values
pub fn add_method(
service: Service(req_meta, state, message),
method: method.Method(req, resp),
handler: fn(req, req_meta, state) -> #(
Result(resp, ServiceError),
req_meta,
message,
),
) -> Service(req_meta, state, message)
Registers one method implementation.
Your handler receives the deserialized request, request metadata, and
application state, and returns:
Ok(response)for successError(ServiceError(...))for controlled HTTP errors- a message which will be returned by
handle_requestand can be used to update the application state.
pub fn handle_request(
service: Service(req_meta, state, message),
body: String,
req_meta: req_meta,
state: state,
) -> #(RawResponse, message)
Handles one incoming request body and returns (raw_response, message).
The value passed to body must depend on the request type:
- For POST requests, pass the raw request body text.
- For GET requests, pass the decoded query payload.
Example:
let #(raw, message) =
service.handle_request(svc, input, Nil, state)
process.send(reply, raw)
case message {
option.Some(new_state) -> state_loop(subject, svc, new_state)
option.None -> state_loop(subject, svc, state)
}
pub fn new(
empty_message empty_message: message,
) -> Service(req_meta, state, message)
Creates a new service.
Default behavior:
- unrecognized values when deserializing requests are dropped.
- unknown error messages are not exposed to clients.
- errors are not logged.
empty_message is returned by handle_request when no method-produced
message is available (for example "list", "studio", malformed input
or unknown method).
pub fn set_can_send_unknown_error_message(
service: Service(req_meta, state, message),
can_send: fn(ServiceErrorInfo(req_meta, state)) -> Bool,
) -> Service(req_meta, state, message)
Decides whether unknown internal error messages may be sent to clients.
The safe default is False. Expose messages only when you are sure they do
not leak sensitive information.
pub fn set_error_logger(
service: Service(req_meta, state, message),
logger: fn(ServiceErrorInfo(req_meta, state)) -> Nil,
) -> Service(req_meta, state, message)
Sets a callback invoked whenever a method returns an error. for logging the error.
pub fn set_keep_unrecognized_values(
service: Service(req_meta, state, message),
keep: Bool,
) -> Service(req_meta, state, message)
Controls whether unknown request fields are preserved while decoding.
Only enable this for data from trusted sources. Malicious actors could inject fields with IDs not yet defined in your schema.