# 16 · Build Your First JSON API

English narration · HHY 1.7.0

Serve a local /hello route and read a query parameter using the built-in Web Runtime.

## 00:00:00.000 — From client to server

Until now, our scripts have consumed data or produced files. In this lesson, an HHY program will answer an HTTP request. We will create one local route called hello, read a name from the query string, and return a JSON object. The response you see is produced by the built in Web Runtime. This is the final project in the first course section, and it connects our knowledge of functions and data values to a running network service.

```
GET /hello?name=Ada
200 OK
{"ok": true, "name": "Ada"}
```

## 00:00:33.430 — Use the built in Web module

Create app dot HHY and import web. This gives us the core application and response builders described in the Web Runtime chapter. We are using those directly, so this example does not require installing a separate web framework. The whole application is small enough to read at once, but it still has three distinct responsibilities: a handler that computes a response, a route that selects the handler, and a listener that accepts connections.

```
import web
```

## 00:01:06.490 — Write a response function

Define a function named hello with one request parameter. The request exposes parsed query parameters, so we read name and put it in a small response object. Web JSON creates the HTTP response representation from ordinary data. Notice the difference from printing JSON in a command line script: a printed line goes to the server's terminal, while a returned Web response goes to the client that made the request. The handler's job is to return that response.

```
fn hello(request) {
    return web.json({ ok: true, name: request.query_params.name })
}
```

## 00:01:41.240 — Connect the route

Create an application and register a GET route at slash hello. The route path determines which incoming requests should reach our function. The function name is passed as a value, so the registration step does not call the handler with a made up request. The runtime invokes it later for a matching request. Keep the leading slash in the route and use the same path in your test command; an incorrect URL should not be mistaken for a failure to start the server.

```
web.app()
    |> web.get("/hello", hello)
```

## 00:02:14.050 — Bind a local listener

Add the listener with an explicit host, port, and worker count. Loopback keeps this tutorial server on your own computer. Port ninety three sixteen is separate from the documentation website, so the two applications can run at the same time. One worker is sufficient for this example. The application is now a persistent service: after starting it, the terminal remains occupied while it waits for requests. That waiting state is expected, rather than a script that forgot to finish.

```
    |> web.listen({ host: "127.0.0.1", port: 9316, workers: 1 })
```

## 00:02:48.740 — Start and request

Run HHY serve with the application file, then open another terminal and request the local URL with curl. Quote the URL so your shell does not interpret the question mark as a filename pattern. Inspect the returned JSON and confirm that name is Ada. You have now exercised the full path: the listener accepted a connection, the route selected the function, the function read query data, and the runtime sent its JSON response back to the client.

```
hhy serve app.hhy
# In a second terminal:
curl "http://127.0.0.1:9316/hello?name=Ada"
```

## 00:03:23.750 — Separate common failure cases

If the request cannot connect, check whether the server is still running and whether the port matches the listener. If it connects but the path is unknown, investigate route registration and the URL. These are different failure layers and deserve different fixes. The supplied verifier checks the successful response and a missing route, then terminates only the server process it started. During manual practice, stop your server with Control C when you finish so a later run can bind the same port.

```
Wrong port → connection problem
Wrong path → route problem
Correct path + query → JSON response
```

## 00:03:59.290 — Practice and finish the first section

Change the query name to Grace and predict the response before sending the request. Then add a message field to the returned object, restart the server, and verify the new output. Keep deployment, authentication, and more elaborate service architecture for a separate lesson. You now have the complete first section's toolkit: scripts, streams, files, data conversion, commands, HTTP clients, bounded parallelism, event driven work, and a small JSON API. Use the downloaded examples as starting points, and keep checking actual results as you adapt them.

```
Try /hello?name=Grace
Then add a message field to the response.
```

