Type-safe routing
Ktor provides the Resources plugin that allows you to implement type-safe routing. To accomplish this, you need to create a class that should act as a typed route and then annotate this class using the @Resource keyword. Note that the @Resource annotation has @Serializable behavior provided by the kotlinx.serialization library.
Add dependencies
Add kotlinx.serialization
Given that resource classes should have @Serializable behavior, you need to add the Kotlin serialization plugin as described in the Setup section.
Add Resources dependencies
To use Resources, you need to include the ktor-server-resources artifact in the build script:
Install Resources
To install the Resources plugin to the application, pass it to the install function in the specified module. The code snippets below show how to install Resources...
... inside the
embeddedServerfunction call.... inside the explicitly defined
module, which is an extension function of theApplicationclass.
Create resource classes
Each resource class should have the @Resource annotation. Below, we'll take a look at several examples of resource classes - defining a single path segment, query and path parameters, and so on.
Resource URL
The example below shows how to define the Articles class that specifies a resource responding on the /articles path.
Resources with a query parameter
The Articles class below has the sort string property that acts as a query parameter and allows you to define a resource responding on the following path with the sort query parameter: /articles?sort=new.
Resources with nested classes
You can nest classes to create resources that contain several path segments. Note that in this case nested classes should have a property with an outer class type. The example below shows a resource responding on the /articles/new path.
Resources with a path parameter
The example below demonstrates how to add the nested {id} integer path parameter that matches a path segment and captures it as a parameter named id.
As an example, this resource can be used to respond on /articles/12.
Example: A resource for CRUD operations
Let's summarize the examples above and create the Articles resource for CRUD operations.
This resource can be used to list all articles, post a new article, edit it, and so on. We'll see how to define route handlers for this resource in the next chapter.
Define route handlers
To define a route handler for a typed resource, you need to pass a resource class to a verb function (get, post, put, and so on). For example, a route handler below responds on the /articles path.
The example below shows how to define route handlers for the Articles resource created in Example: A resource for CRUD operations. Note that inside the route handler you can access the Article as a parameter and obtain its property values.
Here are several tips on handling requests for each endpoint:
get<Articles>This route handler is supposed to return all articles sorted according to the
sortquery parameter. For instance, this might be an HTML page or a JSON object with all articles.get<Articles.New>This endpoint responds with a web form containing fields for creating a new article.
post<Articles>The
post<Articles>endpoint is supposed to receive parameters sent using a web form. Ktor also allows you to receive JSON data as an object using theContentNegotiationplugin.get<Articles.Id>This route handler is supposed to return an article with the specified identifier. This might be an HTML page showing an article or a JSON object with article data.
get<Articles.Id.Edit>This endpoint responds with a web form containing fields for editing an existing article.
put<Articles.Id>Similarly to the
post<Articles>endpoint, theputhandler receives form parameters sent using a web form.delete<Articles.Id>This route handler deletes an article with the specified identifier.
You can find the full example here: resource-routing.
Build links from resources
Besides using resource definitions for routing, they can also be used to build links. This is sometimes called reverse routing. Building links from resources might be helpful if you need to add these links to an HTML document created with HTML DSL or if you need to generate a redirection response.
The Resources plugin extends Application with the overloaded href method, which allows you to generate a link from a Resource. For instance, the code snippet below creates a link for the Edit resource defined above:
Since the grandparent Articles resource defines the sort query parameter with the default value new, the link variable contains:
To generate URLs that specify the host and protocol, you can supply the href method with URLBuilder. Additional query params can also be specified using the URLBuilder, as shown in this example:
The link variable subsequently contains:
Example
The example below shows how to add links built from resources to the HTML response:
You can find the full example here: resource-routing.