Skip to content

Commit 798d104

Browse files
committed
feat: add async handler support in HttpServer and update README with async example
- Updated HttpServer to support async handlers for all HTTP methods (GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD, TRACE, CONNECT, ALL). - Added an example of an async GET handler in the README to demonstrate the new functionality. - Enhanced the existing async/await implementation for improved I/O operations.
1 parent 952accc commit 798d104

4 files changed

Lines changed: 68 additions & 46 deletions

File tree

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,18 @@ The library now supports async/await for I/O operations:
2222
Async functions can be called using the `!!` operator and must be wrapped in
2323
`run_async` when called from synchronous contexts.
2424

25+
### Async /GET Example
26+
27+
```moonbit
28+
// async json data example
29+
server.get("/async_data", async fn(
30+
_req : @mocket.HttpRequest,
31+
_res : @mocket.HttpResponse
32+
) {
33+
{ "name": "John Doe", "age": 30, "city": "New York" }
34+
})
35+
```
36+
2537
```moonbit
2638
run_async(fn() {
2739
try {

moon.mod.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "oboard/mocket",
3-
"version": "0.2.2",
3+
"version": "0.2.3",
44
"deps": {
55
"oboard/mimetype": "0.1.4",
66
"yj-qin/regexp": "0.3.2",

src/lib/server.mbt

Lines changed: 48 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ type! NetworkError derive(Show)
88
type! ExecError derive(Show)
99

1010
///|
11-
// fn run_async(f : async() -> Unit) -> Unit = "%async.run"
11+
fn run_async(f : async() -> Unit) -> Unit = "%async.run"
1212

1313
///|
1414
async fn suspend[T, E : Error](f : ((T) -> Unit, (E) -> Unit) -> Unit) -> T!E = "%async.suspend"
@@ -38,7 +38,7 @@ pub(all) struct HttpRequest {
3838
///|
3939
pub(all) struct HttpServer {
4040
port : Int
41-
mappings : Map[String, (HttpRequest, HttpResponse) -> Json]
41+
mappings : Map[String, async(HttpRequest, HttpResponse) -> Json]
4242
}
4343

4444
///|
@@ -101,40 +101,43 @@ pub fn listen(
101101
},
102102
}
103103
let response : HttpResponse = { id, statusCode: 200, headers: {} }
104-
fn doHandler(reqFn : ((HttpRequest, HttpResponse) -> Json)?) {
104+
fn doHandler(reqFn : ( async(HttpRequest, HttpResponse) -> Json)?) {
105105
match reqFn {
106-
Some(handler) => {
107-
let result = handler(request, response)
108-
match result {
109-
Object({ "_T": "html", "data": data }) => {
110-
response.writeHead(200, { "Content-Type": "text/html" })
111-
response.end(data)
106+
Some(handler) =>
107+
run_async(fn() {
108+
let result = handler!!(request, response)
109+
match result {
110+
Object({ "_T": "html", "data": data }) => {
111+
response.writeHead(200, { "Content-Type": "text/html" })
112+
response.end(data)
113+
}
114+
Object({ "_T": "file", "path": String(path) }) => {
115+
let mime = @mimetype.new()
116+
let mimeType = mime.getType(path)
117+
response.writeHead(200, {
118+
"Content-Type": mimeType.or(
119+
"application/octet-stream",
120+
)
121+
|> String,
122+
})
123+
response.end(result)
124+
}
125+
Object(_) => {
126+
response.writeHead(200, {
127+
"Content-Type": "application/json",
128+
})
129+
response.end(result)
130+
}
131+
String(_) => {
132+
response.writeHead(200, { "Content-Type": "text/plain" })
133+
response.end(result)
134+
}
135+
_ => {
136+
response.writeHead(200, { "Content-Type": "text/plain" })
137+
response.end(result)
138+
}
112139
}
113-
Object({ "_T": "file", "path": String(path) }) => {
114-
let mime = @mimetype.new()
115-
let mimeType = mime.getType(path)
116-
response.writeHead(200, {
117-
"Content-Type": mimeType.or("application/octet-stream")
118-
|> String,
119-
})
120-
response.end(result)
121-
}
122-
Object(_) => {
123-
response.writeHead(200, {
124-
"Content-Type": "application/json",
125-
})
126-
response.end(result)
127-
}
128-
String(_) => {
129-
response.writeHead(200, { "Content-Type": "text/plain" })
130-
response.end(result)
131-
}
132-
_ => {
133-
response.writeHead(200, { "Content-Type": "text/plain" })
134-
response.end(result)
135-
}
136-
}
137-
}
140+
})
138141
None => {
139142
response.writeHead(404, { "Content-Type": "text/plain" })
140143
response.end("Not Found")
@@ -196,7 +199,7 @@ fn handleFunc(
196199
self : HttpServer,
197200
reqMethod : String,
198201
mapping : String,
199-
handler : (HttpRequest, HttpResponse) -> Json
202+
handler : async(HttpRequest, HttpResponse) -> Json
200203
) -> Unit {
201204
self.mappings[reqMethod + " " + mapping] = handler
202205
(binding.send)("http.handle", [String(reqMethod), String(mapping)])
@@ -206,7 +209,7 @@ fn handleFunc(
206209
pub fn get(
207210
self : HttpServer,
208211
mapping : String,
209-
handler : (HttpRequest, HttpResponse) -> Json
212+
handler : async(HttpRequest, HttpResponse) -> Json
210213
) -> Unit {
211214
handleFunc(self, "GET", mapping, handler)
212215
}
@@ -215,7 +218,7 @@ pub fn get(
215218
pub fn post(
216219
self : HttpServer,
217220
mapping : String,
218-
handler : (HttpRequest, HttpResponse) -> Json
221+
handler : async(HttpRequest, HttpResponse) -> Json
219222
) -> Unit {
220223
handleFunc(self, "POST", mapping, handler)
221224
}
@@ -224,7 +227,7 @@ pub fn post(
224227
pub fn put(
225228
self : HttpServer,
226229
mapping : String,
227-
handler : (HttpRequest, HttpResponse) -> Json
230+
handler : async(HttpRequest, HttpResponse) -> Json
228231
) -> Unit {
229232
handleFunc(self, "PUT", mapping, handler)
230233
}
@@ -233,7 +236,7 @@ pub fn put(
233236
pub fn delete(
234237
self : HttpServer,
235238
mapping : String,
236-
handler : (HttpRequest, HttpResponse) -> Json
239+
handler : async(HttpRequest, HttpResponse) -> Json
237240
) -> Unit {
238241
handleFunc(self, "DELETE", mapping, handler)
239242
}
@@ -242,7 +245,7 @@ pub fn delete(
242245
pub fn patch(
243246
self : HttpServer,
244247
mapping : String,
245-
handler : (HttpRequest, HttpResponse) -> Json
248+
handler : async(HttpRequest, HttpResponse) -> Json
246249
) -> Unit {
247250
handleFunc(self, "PATCH", mapping, handler)
248251
}
@@ -251,7 +254,7 @@ pub fn patch(
251254
pub fn options(
252255
self : HttpServer,
253256
mapping : String,
254-
handler : (HttpRequest, HttpResponse) -> Json
257+
handler : async(HttpRequest, HttpResponse) -> Json
255258
) -> Unit {
256259
handleFunc(self, "OPTIONS", mapping, handler)
257260
}
@@ -260,7 +263,7 @@ pub fn options(
260263
pub fn head(
261264
self : HttpServer,
262265
mapping : String,
263-
handler : (HttpRequest, HttpResponse) -> Json
266+
handler : async(HttpRequest, HttpResponse) -> Json
264267
) -> Unit {
265268
handleFunc(self, "HEAD", mapping, handler)
266269
}
@@ -269,7 +272,7 @@ pub fn head(
269272
pub fn trace(
270273
self : HttpServer,
271274
mapping : String,
272-
handler : (HttpRequest, HttpResponse) -> Json
275+
handler : async(HttpRequest, HttpResponse) -> Json
273276
) -> Unit {
274277
handleFunc(self, "TRACE", mapping, handler)
275278
}
@@ -278,7 +281,7 @@ pub fn trace(
278281
pub fn connect(
279282
self : HttpServer,
280283
mapping : String,
281-
handler : (HttpRequest, HttpResponse) -> Json
284+
handler : async(HttpRequest, HttpResponse) -> Json
282285
) -> Unit {
283286
handleFunc(self, "CONNECT", mapping, handler)
284287
}
@@ -287,7 +290,7 @@ pub fn connect(
287290
pub fn all(
288291
self : HttpServer,
289292
mapping : String,
290-
handler : (HttpRequest, HttpResponse) -> Json
293+
handler : async(HttpRequest, HttpResponse) -> Json
291294
) -> Unit {
292295
handleFunc(self, "ALL", mapping, handler)
293296
}

src/main/main.mbt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ fn main {
4040
) {
4141
String("<h1>Hello, World!</h1>")
4242
})
43+
// async json data example
44+
server.get("/async_data", async fn(
45+
_req : @mocket.HttpRequest,
46+
_res : @mocket.HttpResponse
47+
) {
48+
{ "name": "John Doe", "age": 30, "city": "New York" }
49+
})
4350
// json data example
4451
server.get("/data", fn(
4552
_req : @mocket.HttpRequest,

0 commit comments

Comments
 (0)