01 / EDGE
service
ServiceConf (typed config: name, host, port, timeout, log level) + Server tie the application and a middleware onion into one runnable ASGI application; logging is a built-in layer.
WHERE IT SITS
INTERFACE
struct ServerstructA moonzero service: its config plus the assembled application (a moonapi App with any middleware already wrapped around it).
fn Server::new(conf : @conf.ServiceConf, app : @moonapi.App) -> ServerfnAssemble a service from config and a moonapi application.
fn Server::use_(self : Server, mw : @handler.Middleware) -> ServerfnWrap the current application in another middleware layer (outermost last).
fn Server::to_asgi(self : Server) -> @moonasgi.AsgiAppfnThe assembled AsgiApp, ready for a server (mooncat) to run.
fn Server::describe(self : Server) -> StringfnA human-readable description of what this service binds to.
fn Server::files( self : Server, prefix : String, files : @handler.Files) -> ServerfnServe files under prefix. The mount is a layer, so file responses still pass through CORS, tracing and access logging.
fn Server::mounted(self : Server) -> Array[String]fnThe prefixes this service serves files from.
fn not_found( app : @moonapi.App, handler : (@moonapi.Context) -> @http.Response) -> UnitfnReplace the reply an unmatched request gets. The handler runs inside the application, so the chain around it — tracing, access logging, CORS — has already run.
fn not_allowed( app : @moonapi.App, handler : (@moonapi.Context) -> @http.Response) -> UnitfnReplace the reply a request with a known path but an unsupported method gets, normally 405 Method Not Allowed.