Write route handlers

How could a web framework without programming ability be called framework? By the end of this tutorial, you'll learn how to write route handlers and return different kind of responses to the frontend.

Create a project

Let's create a new project for programming code.

Now we've just created a barebone Teo server app. Don't forget to create a schema file like before. Create a file named schema.teo in the root directory of the project with the following content.

server {
  bind: ("0.0.0.0", 5051)
}
 
request middlewares [logRequest]

Run this command to start our server:

This time we're not using Teo CLI because we want our custom code to be loaded and compiled. Now a barebone server is started with every routes lead to NotFound error with 404 code.

Most of the times, the routes that we write are for API interactions. Frontend clients request these APIs for structured data. JSON is the most popular data format. Depending on business needs, some API routes return HTML documents, images and files. These routes are not designed for frontend clients to intercharge data with. And the response values are not structured data like JSON. Teo will not include these routes in the generated frontend clients. That is, the routes that we write fall into two main categories: API interaction and Non-API interaction.

Non-API interaction

HTML response

Let's begin with create a home page for this server.

Append this to the end of schema.teo.

@map(.get, "/")
declare nonapi handler hello(): Any

With this updated code, we define a handler named "hello" to match what we've declared in our schema. Stop the running server process and restart the server. Navigate to "http://localhost:5051" in a browser, you will see the new home page that we've just write in HTML.

Browser screenshot

In practice, any template engines can be used to generate the HTML content. But it's far beyond this scope.

Empty response

Let's have a rest and write something simple.

Add these to the schema and the source code file.

@map(.get, "/empty")
declare nonapi handler empty(): Any

Restart our server and request to /empty.

curl http://localhost:5051/empty

The output is blank since this is an empty response.

Text response

Let's write a text response which echos user's url segment input.

Add these to our schema.

Run this command to generate interfaces.

We've included the generated path arguments into our code and use it in our handler.

Start our server again.

Now navigate to /echo/hello in the browser. The path argument is printed out.

Browser screenshot

File response

Let's server some static files from a directory.

Create a file at /static/images/girl.webp with the following image.

Browser screenshot

Append this to the end of the schema.

@map(.get, "/static/*path", interface: "StaticPathArguments")
declare nonapi handler static(): Any

Repeat the code generation process.

Start the server again.

Now navigate to /static/images/girl.webp in the browser, and you will see the image. Try typing a non-existing file path, 404 is responded.

Browser screenshot

API interaction

JSON is the only response data format that Teo supports. If you have requirements for other data types. Let us know by firing an issue.

JSON request

Let's add some models and perform some model updates from JSON requests.

Replace schema.teo with this.

Generate the entities again.

This way, Teo becames a normal ORM and developers can write any code to interact data with. The createdAt field is readonly, but through custom handlers, it becomes modifiable.

Form request

Let's try some file uploading. Upload an image to the static directory that we've created before.

Append this to the schema.

@map(path: "/upload")
declare form handler upload(UploadInput): Data<UploadOutput>
 
interface UploadInput {
  file: File
}
 
interface UploadOutput {
  path: String
}

Generate interfaces.

Start our server again.

Now send a form request to /upload. And access the URL of the uploaded file. The uploaded file starts downloading.

Summary

Teo is a great web framework for modeling data and writing route handlers. No matter which programming language is used, Teo try it best to be type safe and reduce duplications. This tutorial is much harder than the previous one. If you have any problems or find bugs with it, let us know by joining our Discord group or firing an issue.