Skip to content

Commit 14c5129

Browse files
committed
add validator library
1 parent 19988c5 commit 14c5129

Some content is hidden

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

53 files changed

+664
-406
lines changed

doc/api/errors.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,23 @@
22

33
You have the freedom to handle errors however you like. However, Lavandula provides a interface for returning JSON errors from your controllers.
44

5+
Errors returned from Lavandula have two fields, a `success` boolean and a `message` string.
56

7+
Currently, to return an error from the
8+
```
9+
return apiResponse("missing body in request");
10+
```
11+
12+
This is a method commonly used in middleware. The point of it is to refrain from returning plain text error messages as JSON is easier to work with and standardise.
13+
14+
Here is an example of this used in some middleware.
615

716
```
17+
middleware(validateJsonBody, ctx, m) {
18+
if (!ctx.hasBody) {
19+
return apiResponse("Error: no JSON body provided.");
20+
}
821
22+
return next(ctx, m);
23+
}
924
```

doc/api/middleware.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,22 @@ HttpResponse myMiddleware(RequestContext ctx, MiddlewareHandler *middleware) {
6464

6565
## Library Middleware
6666

67+
Lavandula provides some common middleware functions to use in your application.
68+
69+
### Console Logger
70+
71+
The logger middleware logs the method and route every time the web server is hit. This is useful for debugging purposes.
72+
73+
```c
74+
AppBuilder builder = createBuilder();
75+
useGlobalMiddleware(&builder, consoleLogger);
76+
```
77+
78+
### JSON Body Validator
79+
80+
The JSON body middleware validates the presence of a JSON body. A bad request will be returned otherwise.
81+
82+
```c
83+
Route rootRoute = root(&app, home);
84+
useLocalMiddleware(&rootRoute, validateJsonBody);
85+
```

doc/api/request_context.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Request Context
2+
3+
The request context is the second argument passed into an `appRoute`. It holds data and resources related to the request routed to this controller endpoint. It also contains the instance of your `App`.
4+
5+
Because calling `jsonParse` on the `request.body` is a very common operation, this is done for you and stored as a field in the `RequestContext`. If the body is not present, you can null check the `body` field itself, or use the boolean `hasBody` field.
6+
7+
```c
8+
appRoute(home, ctx) {
9+
if (!ctx.hasBody) {
10+
return internalServerError("No body!", TEXT_PLAIN);
11+
}
12+
13+
// return the request body for this example
14+
char *body = jsonStringify(ctx.body);
15+
16+
return ok(body, TEXT_PLAIN);
17+
}
18+
```
19+
20+
Do not call `freeJsonBuilder` on the ctx.body as this is done for you once the request returns a response. Don't worry if you forget as it will not crash your program.

doc/api/validator.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# JSON Validation
2+
3+
Lavandula provides a JSON validator interface for ensuring the correct data is being sent to your application.
4+
5+
Start by creating a validator instance. Then you can call various methods to add rules to the validator. The example below calls the `required` method to add expected fields in the JSON body.
6+
7+
Then, call `validate` to check the context body against the previously defined rules. It will return `NULL` if there is no error. Lastly, free the validator instance to clean up resources.
8+
9+
```c
10+
middleware(registerUserValidator, ctx, m) {
11+
JsonValidator v = createValidator();
12+
13+
required(&v, "username");
14+
required(&v, "password");
15+
16+
char *error = validate(&v, ctx.body);
17+
if (error) {
18+
return apiResponse(error);
19+
}
20+
freeValidator(&v);
21+
22+
return next(ctx, m);
23+
}
24+
```
25+
26+
The JSON validator provides automatic validation against the presence of a body. If a body is not present and a validator is used then the following response will be returned.
27+
28+
```json
29+
{
30+
"success": false,
31+
"message": "Request body is missing or malformed."
32+
}
33+
```

doc/sql.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# Lavandula with SQL
22

3-
This file assumes you have a linux-based environment.
4-
53

64

75
## Setting up SqlLite3
File renamed without changes.
Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
#include "lavandula.h"
2-
3-
appRoute(home, ctx) {
4-
return ok("Hello, World", TEXT_PLAIN);
5-
}
6-
7-
int main() {
8-
App app = createApp();
9-
root(&app, home);
10-
11-
runApp(&app);
1+
#include "lavandula.h"
2+
3+
appRoute(home, ctx) {
4+
return ok("Hello, World", TEXT_PLAIN);
5+
}
6+
7+
int main() {
8+
App app = createApp();
9+
root(&app, home);
10+
11+
runApp(&app);
1212
}
Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
1-
#include "../src/include/lavandula.h"
2-
3-
#include "include/lavandula.h"
4-
5-
appRoute(home, ctx) {
6-
return ok("Hello, World!", TEXT_PLAIN);
7-
}
8-
9-
int main(int argc, char *argv[]) {
10-
AppBuilder builder = createBuilder();
11-
12-
// add basic auth into the global middleware pipeline (for all endpoints)
13-
useBasicAuth(&builder);
14-
15-
App app = build(builder);
16-
17-
// add some sample credentials
18-
addBasicCredentials(&app.auth, "admin", "password");
19-
20-
get(&app, "/home", home);
21-
22-
runApp(&app);
1+
#include "../src/include/lavandula.h"
2+
3+
#include "include/lavandula.h"
4+
5+
appRoute(home, ctx) {
6+
return ok("Hello, World!", TEXT_PLAIN);
7+
}
8+
9+
int main(int argc, char *argv[]) {
10+
AppBuilder builder = createBuilder();
11+
12+
// add basic auth into the global middleware pipeline (for all endpoints)
13+
useBasicAuth(&builder);
14+
15+
App app = build(builder);
16+
17+
// add some sample credentials
18+
addBasicCredentials(&app.auth, "admin", "password");
19+
20+
get(&app, "/home", home);
21+
22+
runApp(&app);
2323
}
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)