DOCUMENTATION / CORE FRAMEWORK

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.