1
0
Fork 0
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:
Rene Schallner 2023-01-18 14:26:01 +01:00
parent 3fa538081e
commit c8f9a18dc0
5 changed files with 82 additions and 50 deletions

View file

@ -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;
}
}
// ...
```

View file

@ -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| {

View file

@ -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));

View file

@ -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
View 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
```