mirror of
https://github.com/zigzap/zap.git
synced 2025-10-20 15:14:08 +00:00
more sane endpoints example
This commit is contained in:
parent
3fa538081e
commit
c8f9a18dc0
5 changed files with 82 additions and 50 deletions
45
README.md
45
README.md
|
@ -33,9 +33,8 @@ Here's what works:
|
|||
- **[hello_json](examples/hello_json/hello_json.zig)**: serves you json
|
||||
dependent on HTTP path
|
||||
- **[endpoints](examples/endpoints/)**: a simple JSON REST API example featuring
|
||||
a `/users` endpoint for PUTting/DELETE-ing/GET-ting/POST-ing users and a
|
||||
`/list` endpoint returning the entire user list on GET, together with a static
|
||||
HTML and JavaScript frontend to play around with.
|
||||
a `/users` endpoint for PUTting/DELETE-ing/GET-ting/POST-ing and listing
|
||||
users, together with a static HTML and JavaScript frontend to play with.
|
||||
|
||||
I'll continue wrapping more of facil.io's functionality and adding stuff to zap
|
||||
to a point where I can use it as the JSON REST API backend for real research
|
||||
|
@ -421,11 +420,10 @@ pub fn main() !void {
|
|||
},
|
||||
);
|
||||
|
||||
Endpoints.init(allocator, "/user", "/list");
|
||||
Endpoints.init(allocator, "/users");
|
||||
|
||||
// add endpoints
|
||||
// add endpoint
|
||||
try listener.addEndpoint(Endpoints.getUserEndpoint());
|
||||
try listener.addEndpoint(Endpoints.getUserListEndpoint());
|
||||
|
||||
// fake some users
|
||||
var uid: usize = undefined;
|
||||
|
@ -454,34 +452,26 @@ const zap = @import("zap");
|
|||
const Users = @import("users.zig");
|
||||
const User = Users.User;
|
||||
|
||||
// the Endpoints
|
||||
// the Endpoint
|
||||
|
||||
pub const Self = @This();
|
||||
|
||||
var alloc: std.mem.Allocator = undefined;
|
||||
var endpoint: zap.SimpleEndpoint = undefined;
|
||||
var list_endpoint: zap.SimpleEndpoint = undefined;
|
||||
var users: Users = undefined;
|
||||
|
||||
pub fn init(
|
||||
a: std.mem.Allocator,
|
||||
user_path: []const u8,
|
||||
userlist_path: []const u8,
|
||||
) void {
|
||||
users = Users.init(a);
|
||||
alloc = a;
|
||||
endpoint = zap.SimpleEndpoint.init(.{
|
||||
.path = user_path,
|
||||
.get = getUser,
|
||||
.post = null,
|
||||
.put = null,
|
||||
.delete = null,
|
||||
});
|
||||
list_endpoint = zap.SimpleEndpoint.init(.{
|
||||
.path = userlist_path,
|
||||
.get = listUsers,
|
||||
.post = null,
|
||||
.put = null,
|
||||
.delete = null,
|
||||
.post = postUser,
|
||||
.put = putUser,
|
||||
.delete = deleteUser,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -493,10 +483,6 @@ pub fn getUserEndpoint() *zap.SimpleEndpoint {
|
|||
return &endpoint;
|
||||
}
|
||||
|
||||
pub fn getUserListEndpoint() *zap.SimpleEndpoint {
|
||||
return &list_endpoint;
|
||||
}
|
||||
|
||||
fn userIdFromPath(path: []const u8) ?usize {
|
||||
if (path.len >= endpoint.settings.path.len + 2) {
|
||||
if (path[endpoint.settings.path.len] != '/') {
|
||||
|
@ -508,9 +494,12 @@ fn userIdFromPath(path: []const u8) ?usize {
|
|||
return null;
|
||||
}
|
||||
|
||||
pub fn getUser(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void {
|
||||
_ = e;
|
||||
fn getUser(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void {
|
||||
if (r.path) |path| {
|
||||
// /users
|
||||
if (path.len == e.settings.path.len) {
|
||||
return listUsers(e, r);
|
||||
}
|
||||
if (userIdFromPath(path)) |id| {
|
||||
if (users.get(id)) |user| {
|
||||
if (zap.stringify(user, .{})) |json| {
|
||||
|
@ -521,13 +510,13 @@ pub fn getUser(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn listUsers(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void {
|
||||
fn listUsers(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void {
|
||||
_ = e;
|
||||
var l: std.ArrayList(User) = std.ArrayList(User).init(alloc);
|
||||
if (users.list(&l)) {} else |_| {
|
||||
return;
|
||||
}
|
||||
if (zap.stringifyArrayList(std.ArrayList(User, &l, .{})) |maybe_json| {
|
||||
if (zap.stringifyArrayList(User, &l, .{})) |maybe_json| {
|
||||
if (maybe_json) |json| {
|
||||
_ = r.sendJson(json);
|
||||
}
|
||||
|
@ -535,5 +524,7 @@ pub fn listUsers(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
|
|
|
@ -3,19 +3,17 @@ const zap = @import("zap");
|
|||
const Users = @import("users.zig");
|
||||
const User = Users.User;
|
||||
|
||||
// the Endpoints
|
||||
// the Endpoint
|
||||
|
||||
pub const Self = @This();
|
||||
|
||||
var alloc: std.mem.Allocator = undefined;
|
||||
var endpoint: zap.SimpleEndpoint = undefined;
|
||||
var list_endpoint: zap.SimpleEndpoint = undefined;
|
||||
var users: Users = undefined;
|
||||
|
||||
pub fn init(
|
||||
a: std.mem.Allocator,
|
||||
user_path: []const u8,
|
||||
userlist_path: []const u8,
|
||||
) void {
|
||||
users = Users.init(a);
|
||||
alloc = a;
|
||||
|
@ -26,13 +24,6 @@ pub fn init(
|
|||
.put = putUser,
|
||||
.delete = deleteUser,
|
||||
});
|
||||
list_endpoint = zap.SimpleEndpoint.init(.{
|
||||
.path = userlist_path,
|
||||
.get = listUsers,
|
||||
.post = null,
|
||||
.put = null,
|
||||
.delete = null,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn getUsers() *Users {
|
||||
|
@ -43,10 +34,6 @@ pub fn getUserEndpoint() *zap.SimpleEndpoint {
|
|||
return &endpoint;
|
||||
}
|
||||
|
||||
pub fn getUserListEndpoint() *zap.SimpleEndpoint {
|
||||
return &list_endpoint;
|
||||
}
|
||||
|
||||
fn userIdFromPath(path: []const u8) ?usize {
|
||||
if (path.len >= endpoint.settings.path.len + 2) {
|
||||
if (path[endpoint.settings.path.len] != '/') {
|
||||
|
@ -59,8 +46,11 @@ fn userIdFromPath(path: []const u8) ?usize {
|
|||
}
|
||||
|
||||
fn getUser(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void {
|
||||
_ = e;
|
||||
if (r.path) |path| {
|
||||
// /users
|
||||
if (path.len == e.settings.path.len) {
|
||||
return listUsers(e, r);
|
||||
}
|
||||
if (userIdFromPath(path)) |id| {
|
||||
if (users.get(id)) |user| {
|
||||
if (zap.stringify(user, .{})) |json| {
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
</table>
|
||||
</div>
|
||||
<div class="center">
|
||||
<p><a href="/list">Show JSON for all users</a></p>
|
||||
<p><a href="/users">Show JSON for all users</a></p>
|
||||
</div>
|
||||
<div style="padding:20px; margin-top: 1rem;">
|
||||
<label style="margin-bottom: 10px;">Log Output:</label>
|
||||
|
@ -155,7 +155,7 @@
|
|||
first_name: first_name,
|
||||
last_name: last_name,
|
||||
}
|
||||
sendJSON(data, "/user", "POST")
|
||||
sendJSON(data, "/users", "POST")
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
log("SUCESS: " + JSON.stringify(data));
|
||||
|
@ -167,7 +167,7 @@
|
|||
}
|
||||
|
||||
function deleteUser(id) {
|
||||
fetch("/user/" + id, { method: "DELETE", } )
|
||||
fetch("/users/" + id, { method: "DELETE", } )
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
log("SUCESS: " + JSON.stringify(data));
|
||||
|
@ -186,7 +186,7 @@
|
|||
first_name: firstname,
|
||||
last_name: lastname,
|
||||
}
|
||||
sendJSON(data, "/user/" + id, "PUT")
|
||||
sendJSON(data, "/users/" + id, "PUT")
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
log("SUCESS: " + JSON.stringify(data));
|
||||
|
@ -242,7 +242,7 @@
|
|||
|
||||
|
||||
function getUserList() {
|
||||
fetch("/list", { method: "GET", } )
|
||||
fetch("/users", { method: "GET", } )
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
log("SUCESS: " + JSON.stringify(data));
|
||||
|
|
|
@ -15,11 +15,10 @@ pub fn main() !void {
|
|||
},
|
||||
);
|
||||
|
||||
Endpoints.init(allocator, "/user", "/list");
|
||||
Endpoints.init(allocator, "/users");
|
||||
|
||||
// add endpoints
|
||||
// add endpoint
|
||||
try listener.addEndpoint(Endpoints.getUserEndpoint());
|
||||
try listener.addEndpoint(Endpoints.getUserListEndpoint());
|
||||
|
||||
// fake some users
|
||||
var uid: usize = undefined;
|
||||
|
|
52
wrk/other_measurements.md
Normal file
52
wrk/other_measurements.md
Normal file
|
@ -0,0 +1,52 @@
|
|||
# other measurements
|
||||
|
||||
## zap wrk 'example' with and without logging
|
||||
|
||||
**NO** performance regressions observable:
|
||||
|
||||
With `logging=true`:
|
||||
|
||||
```
|
||||
[nix-shell:~/code/github.com/renerocksai/zap]$ ./wrk/measure.sh zig > out 2> /dev/null
|
||||
|
||||
[nix-shell:~/code/github.com/renerocksai/zap]$ cat out
|
||||
========================================================================
|
||||
zig
|
||||
========================================================================
|
||||
Running 10s test @ http://127.0.0.1:3000
|
||||
4 threads and 400 connections
|
||||
Thread Stats Avg Stdev Max +/- Stdev
|
||||
Latency 343.91us 286.75us 18.37ms 95.58%
|
||||
Req/Sec 162.61k 3.61k 174.96k 76.75%
|
||||
Latency Distribution
|
||||
50% 302.00us
|
||||
75% 342.00us
|
||||
90% 572.00us
|
||||
99% 697.00us
|
||||
6470789 requests in 10.01s, 0.96GB read
|
||||
Requests/sec: 646459.59
|
||||
Transfer/sec: 98.03MB
|
||||
```
|
||||
|
||||
With `logging=false`:
|
||||
|
||||
```
|
||||
[nix-shell:~/code/github.com/renerocksai/zap]$ ./wrk/measure.sh zig
|
||||
Listening on 0.0.0.0:3000
|
||||
========================================================================
|
||||
zig
|
||||
========================================================================
|
||||
Running 10s test @ http://127.0.0.1:3000
|
||||
4 threads and 400 connections
|
||||
Thread Stats Avg Stdev Max +/- Stdev
|
||||
Latency 336.10us 122.28us 14.67ms 88.55%
|
||||
Req/Sec 159.82k 7.71k 176.75k 56.00%
|
||||
Latency Distribution
|
||||
50% 310.00us
|
||||
75% 343.00us
|
||||
90% 425.00us
|
||||
99% 699.00us
|
||||
6359415 requests in 10.01s, 0.94GB read
|
||||
Requests/sec: 635186.96
|
||||
Transfer/sec: 96.32MB
|
||||
```
|
Loading…
Add table
Reference in a new issue