Video course contents16
LESSON 16 · HHY 1.7.0
Build Your First JSON API
Serve a local /hello route and read a query parameter using the built-in Web Runtime.
Your progress stays in this browser. No account needed.
Read the companion manual chapter →
Chapters & transcript
Select a timestamp to jump in the video. Expand a title to read the transcript and code.
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"}Actual response from the local HHY server.
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 webThis example uses the core Runtime, without an extra framework.
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 })
}The handler receives a Web request.
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)Route path and handler are separate values.
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 })Loopback only; leave port 9200 for the documentation website.
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"Expect the JSON object shown at the beginning.
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 responseThe automated verifier also checks an unknown route.
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.Keep the first exercise local and small.
