Skip to content
This repository was archived by the owner on May 12, 2026. It is now read-only.

Commit 51b88e9

Browse files
authored
Merge pull request #285 from Lightbug-HQ/feature/json-support
Add JSON Support
2 parents b78513c + 5e67541 commit 51b88e9

57 files changed

Lines changed: 2474 additions & 3608 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ __pycache__
2222
.mcp.json
2323
.claude
2424
CLAUDE.md
25-
.kli/**
25+
*.xml

README.md

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ Once you have a Mojo project set up locally,
5858

5959
```toml
6060
[dependencies]
61-
lightbug_http = ">=0.26.1.2,<0.26.2"
61+
lightbug_http = ">=0.26.2.0,<0.26.3"
6262
```
6363

6464
3. Run `pixi install` at the root of your project, where `pixi.toml` is located
@@ -151,6 +151,33 @@ struct ExampleRouter(HTTPService):
151151

152152
We plan to add more advanced routing functionality in a future library called `lightbug_api`, see [Roadmap](#roadmap) for more details.
153153

154+
### JSON
155+
156+
Use `json_decode[T]` to deserialize a request body into a typed struct, and `Json(value)` to return a JSON response:
157+
158+
```mojo
159+
from lightbug_http import OK, HTTPRequest, HTTPResponse, HTTPService
160+
from lightbug_http.http.json import Json, json_decode
161+
162+
@fieldwise_init
163+
struct GreetRequest(Movable, Defaultable):
164+
var name: String
165+
fn __init__(out self): self.name = ""
166+
167+
@fieldwise_init
168+
struct GreetResponse(Movable, Defaultable):
169+
var message: String
170+
fn __init__(out self): self.message = ""
171+
172+
@fieldwise_init
173+
struct JsonService(HTTPService):
174+
fn func(mut self, req: HTTPRequest) raises -> HTTPResponse:
175+
var body = json_decode[GreetRequest](req)
176+
return OK(Json(GreetResponse(String("Hello, ", body.name, "!"))))
177+
```
178+
179+
JSON support is powered by [emberjson](https://github.com/bgreni/EmberJson).
180+
154181

155182
<p align="right">(<a href="#readme-top">back to top</a>)</p>
156183

@@ -190,7 +217,7 @@ Check out the examples directory for more example services built with Lightbug,
190217

191218
We're working on support for the following (contributors welcome!):
192219

193-
- [ ] [JSON support](https://github.com/saviorand/lightbug_http/issues/4)
220+
- [x] [JSON support](https://github.com/saviorand/lightbug_http/issues/4)
194221
- [ ] Complete HTTP/1.x support compliant with RFC 9110/9112 specs (see issues)
195222
- [ ] [SSL/HTTPS support](https://github.com/saviorand/lightbug_http/issues/20)
196223
- [ ] [Multiple simultaneous connections](https://github.com/saviorand/lightbug_http/issues/5), [parallelization and performance optimizations](https://github.com/saviorand/lightbug_http/issues/6)

examples/echo_server/pixi.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ server = "mojo run server.mojo"
1111
client = "mojo run client.mojo"
1212

1313
[dependencies]
14-
mojo = ">=0.26.1.0,<0.26.2.0"
14+
mojo = ">=0.26.2.0,<0.26.3"
1515
curl_wrapper = { git = "https://github.com/thatstoasty/mojo-curl.git", branch = "main", subdirectory = "shim" }
1616
floki = ">=0.1.0,<0.2"
17-
lightbug_http = ">=0.26.1.2,<0.26.2.0"
17+
lightbug_http = ">=0.26.2.0,<0.26.3"

examples/json_service/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# JSON Service
2+
3+
A simple JSON API example using `lightbug_http`. The server accepts a POST request with a JSON body and returns a JSON response.
4+
5+
To run the server:
6+
7+
```bash
8+
pixi run server
9+
```
10+
11+
Then send a request:
12+
13+
```bash
14+
curl -X POST http://localhost:8080/greet \
15+
-H "Content-Type: application/json" \
16+
-d '{"name": "Alice"}'
17+
# {"message":"Hello, Alice!"}
18+
```

examples/json_service/pixi.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[workspace]
2+
channels = ["https://conda.modular.com/max", "https://repo.prefix.dev/modular-community", "https://repo.prefix.dev/mojo-community", "conda-forge"]
3+
name = "json_service"
4+
platforms = ["osx-arm64", "linux-64", "linux-aarch64"]
5+
version = "0.1.0"
6+
preview = ["pixi-build"]
7+
8+
[tasks]
9+
server = "mojo run server.mojo"
10+
11+
[dependencies]
12+
mojo = ">=2.0,<0.26.3"
13+
lightbug_http = ">=0.26.2.0,<0.26.3"

examples/json_service/server.mojo

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from lightbug_http import OK, NotFound, HTTPRequest, HTTPResponse, HTTPService, Server
2+
from lightbug_http.http.json import Json, json_decode
3+
4+
5+
@fieldwise_init
6+
struct GreetRequest(Movable, Defaultable):
7+
var name: String
8+
9+
fn __init__(out self):
10+
self.name = ""
11+
12+
13+
@fieldwise_init
14+
struct GreetResponse(Movable, Defaultable):
15+
var message: String
16+
17+
fn __init__(out self):
18+
self.message = ""
19+
20+
21+
@fieldwise_init
22+
struct JsonService(HTTPService):
23+
fn func(mut self, req: HTTPRequest) raises -> HTTPResponse:
24+
if req.uri.path == "/greet":
25+
var body = json_decode[GreetRequest](req)
26+
var response = GreetResponse(String("Hello, ", body.name, "!"))
27+
return OK(Json(response))
28+
return NotFound(req.uri.path)
29+
30+
31+
fn main() raises:
32+
var server = Server()
33+
var handler = JsonService()
34+
server.listen_and_serve("localhost:8080", handler)

lightbug.mojo

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from lightbug_http import Welcome
2+
from lightbug_http.server import Server
3+
from std.os.env import getenv
4+
5+
6+
fn main() raises:
7+
var server = Server()
8+
var handler = Welcome()
9+
10+
var host = getenv("DEFAULT_SERVER_HOST", "localhost")
11+
var port = getenv("DEFAULT_SERVER_PORT", "8080")
12+
13+
server.listen_and_serve(host + ":" + port, handler)

lightbug_http/__init__.mojo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ from lightbug_http.service import Counter, HTTPService, Welcome
44
from lightbug_http.uri import URI
55

66
from lightbug_http.cookie import Cookie, RequestCookieJar, ResponseCookieJar
7-
from lightbug_http.http import OK, HTTPRequest, HTTPResponse, NotFound, SeeOther, StatusCode
7+
from lightbug_http.http import OK, HTTPRequest, HTTPResponse, NotFound, SeeOther, StatusCode, Json, json_decode, JsonSerializable, JsonDeserializable

0 commit comments

Comments
 (0)