// The assembled service: config, application, middleware chain, and the knobs
// that are set on the server rather than on a route.
///|
/// A moonzero service: its config plus the assembled application (a moonapi App
/// with any middleware already wrapped around it).
pub struct Server {
conf : @conf.ServiceConf
handler : @moonasgi.AsgiApp
mounted : Array[String]
}
///|
/// Assemble a service from config and a moonapi application.
pub fn Server::new(conf : @conf.ServiceConf, app : @moonapi.App) -> Server {
{ conf, handler: app.to_asgi(), mounted: [], }
}
///|
/// Wrap the current application in another middleware layer (outermost last).
pub fn Server::use_(self : Server, mw : @handler.Middleware) -> Server {
{ conf: self.conf, handler: mw(self.handler), mounted: self.mounted, }
}
///|
/// The assembled `AsgiApp`, ready for a server (mooncat) to run.
pub fn Server::to_asgi(self : Server) -> @moonasgi.AsgiApp {
self.handler
}
///|
/// A human-readable description of what this service binds to.
pub fn Server::describe(self : Server) -> String {
self.conf.name +
" listening on " +
self.conf.host +
":" +
self.conf.port.to_string()
}
///|
/// Serve `files` under `prefix`. The mount is a layer, so file responses still pass
/// through CORS, tracing and access logging.
pub fn Server::files(
self : Server,
prefix : String,
files : @handler.Files,
) -> Server {
{
conf: self.conf,
handler: @handler.file_server(files, prefix)(self.handler),
mounted: [..self.mounted, prefix],
}
}
///|
/// The prefixes this service serves files from.
pub fn Server::mounted(self : Server) -> Array[String] {
self.mounted
}
///|
/// Replace the reply an unmatched request gets (← `WithNotFoundHandler`). The
/// handler runs inside the application, so the chain around it — tracing, access
/// logging, CORS — has already run.
pub fn not_found(
app : @moonapi.App,
handler : (@moonapi.Context) -> @http.Response,
) -> Unit {
app.add_status_handler(404, handler)
}
///|
/// Replace the reply a request with a known path but an unsupported method gets
/// (← `WithNotAllowedHandler`), normally `405 Method Not Allowed`.
pub fn not_allowed(
app : @moonapi.App,
handler : (@moonapi.Context) -> @http.Response,
) -> Unit {
app.add_status_handler(405, handler)
}