Request parsing, forms and validation
This lesson extends the Hello World application. You will read a query parameter, submit an HTML form, send JSON and return useful errors.
1. Read a query parameter
Add a GET handler and register it on /greet:
from mojara import App, Request, Response
def greet(req: Request) -> Response:
var name = req.query.get("name", "World")
return Response.html("<h1>Hello, " + name + "!</h1>")
def main() raises:
var app = App()
app.get("/greet", greet)
app.run(port=8000)
req.query.get("name", "World") reads the URL's name value; the second argument supplies a default. The handler returns an HTML response.
Try it:
curl "http://127.0.0.1:8000/greet?name=Amina"
Expected body: <h1>Hello, Amina!</h1>. Visiting /greet without a parameter displays Hello, World!.
Before inserting user-provided values into HTML, escape them. The example demonstrates parameter access; do not directly interpolate unescaped input in a public application.
2. Display a form and receive a POST
Register a GET handler to display a form and a POST handler to process it:
def show_form(req: Request) -> Response:
return Response.html("""
<form method="post" action="/contact">
<label>Name <input name="name" required></label>
<button type="submit">Send</button>
</form>
""")
def submit_form(req: Request) -> Response:
var name = req.form.get("name", "")
if len(name.strip()) == 0:
return Response.json('{"error":"Name is required"}', status=422)
return Response.json('{"message":"Received"}', status=201)
Inside main(), register the two methods on the same URL:
app.get("/contact", show_form)
app.post("/contact", submit_form)
The browser loads the form with GET, then sends its fields with POST. req.form.get reads a submitted field. The empty-name branch returns status 422 and a clear message.
3. Submit and validate JSON
The client must send JSON with the application/json content type.
def create_user(req: Request) -> Response:
var data = req.json()
var email = data.get("email", "").strip()
if len(email) == 0:
return Response.json('{"error":"email is required"}', status=422)
if "@" not in email:
return Response.json('{"error":"email must be valid"}', status=422)
return Response.json('{"created":true}', status=201)
Register this handler in main():
app.post("/api/users", create_user)
Send a valid request:
curl -i -X POST http://127.0.0.1:8000/api/users \
-H "Content-Type: application/json" \
-d '{"email":"amina@example.com"}'
Expected: HTTP 201 and {"created":true}.
Send an invalid request:
curl -i -X POST http://127.0.0.1:8000/api/users \
-H "Content-Type: application/json" \
-d '{"email":"invalid"}'
Expected: HTTP 422 with {"error":"email must be valid"}.
4. Understand request errors
| Code | When you use it | Example |
|---|---|---|
| 400 | Malformed request body | Broken JSON syntax |
| 401 | Authentication required | No login/session |
| 403 | Insufficient permission | Regular user attempts admin operation |
| 404 | Resource not found | Unknown user ID |
| 405 | Unsupported method | DELETE on a GET-only route |
| 415 | Unsupported request content type | XML when only JSON is accepted |
| 422 | Valid JSON but invalid fields | Missing email |
5. What you learned
You can obtain values from query strings, render and process forms, parse JSON, validate required fields and send meaningful HTTP status codes. Continue with Uploads to accept files or Routing for additional URL patterns.