Finishing My API Routing System With Toolips
Continuing my API routing project by adding a Parent Routing system.
Finishing My API Routing System With Toolips
Continuing my API routing project by adding a Parent Routing system.

api and parent routing
In my last article, I created a new Toolips extension that streamlines the creation of APIs. The result is pretty convenient for building APIs, turning code like this:
addition = route("/") do c::AbstractConnection
args = get_args(c)
x = parse(Int64, args[:x])
y = parse(Int64, args[:y])
write!(c, x + y)
end
Into a concise and convenient form:
adder_r = api_route((c, x::Int64, y::Int64) -> write!(c, x + y), GET, "/add")
The route goes from taking several steps to becoming a one-liner. Those are some pretty awesome results. This article acts as a part two to the article where we created this system, so if you would like to read it for more context here is a link:
[embed]Modding My Web Framework With An API Router multiple dispatch routingmedium.com
Today I wanted to take this project a bit further by adding routes that combine POST and GET requests into the same target. I will also be further expanding on this project further by building another project to help implement this system into any website.
combined API routes
In order to make routes that easily take a GET and POST request in the same route, we will make a simple structure that holds both routes and the actual path for our page.
struct CombinedAPIRoute <: AbstractAPIRoute
path::String
routes::Pair{APIRoute{:get}, APIRoute{:post}}
end
And I will add another api_router Method to make this route from two routes.
api_route(r1::APIRoute{:get}, r2::APIRoute{:post}) = begin
path = r1.path
combined = CombinedAPIRoute(path, r1 => r2)
r1.path = ""
r2.path = ""
combined::CombinedAPIRoute
end
api_route(r1::APIRoute{:post}, r2::APIRoute{:get}) = api_route(r2, r1)
Now we will make a simple route! dispatch that calls different routes depending on the Method . I will use get_method , a handy function from Toolips that takes our Connection .
function route!(c::AbstractConnection, route::CombinedAPIRoute)
if get_method(c) == "POST"
route!(c, route.routes[2])
else
route!(c, route.routes[1])
end
end
A full list of getters, like get_method are available in the [Toolips reference](https://chifidocs.com/toolips/Toolips/reference). With those small functions out of the way our new route is fully implemented.
struct CombinedAPIRoute <: AbstractAPIRoute
path::String
routes::Pair{APIRoute{:get}, APIRoute{:post}}
end
function route!(c::AbstractConnection, route::CombinedAPIRoute)
if get_method(c) == "POST"
route!(c, route.routes[2])
else
route!(c, route.routes[1])
end
end
api_route(r1::APIRoute{:get}, r2::APIRoute{:post}) = begin
path = r1.path
combined = CombinedAPIRoute(path, r1 => r2)
r1.path = ""
r2.path = ""
combined::CombinedAPIRoute
end
api_route(r1::APIRoute{:post}, r2::APIRoute{:get}) = api_route(r2, r1)
Now we will finish the project by creating a new combined route inside of our test API from the last article. As part of building this project originally, we were using this post_test2 function to test the automatic translation of incoming JSON to Julia dictionaries.
post_test2 = (c::AbstractConnection, info::Dict) -> begin
write!(c, "information has been sent: $(info["x"])")
end
We will be reusing this function, only now our actual route will be /api/age , and we will combine it with our GET API for getting the age of people in our dictionary.
post2 = api_route(post_test2, POST, "/api/age")
age_route = (c, username) -> begin
if haskey(users, username)
write!(c, users[username][:age])
else
write!(c, "user $username not found!")
end
end
age = api_route(age_route, GET, "/api/age")
Now to create our combined route:
post_and_age = api_route(age, post2)
We finish by making sure to export the new route.
export post_and_age
Now let’s try it out! First we will post:
julia> start!(ToolipsAPIRouter.APITestServer)
[ Info: Listening on: 127.0.0.1:8000, thread id: 1
pid process type name active
–––– ––––––––––––––––––––––––– ––––––––––––––––––––––––––––––––––––– ––––––
2303 ParametricProcesses.Async ToolipsAPIRouter.APITestServer router true
julia> Toolips.post("http://127.0.0.1:8000/api/age", "{\"x\" : 5}")
"information has been sent: 5"
And then get:

Perfect!
Implementing parent routes
Parent routing is a different idea entirely, and isn’t specifically reserved for building APIs. The goal of this project is for multiple routers to work at the same time by allowing routes to be organized according to their router type. This is loosely connected to our new API-building system,
We will be holding our routes under a ParentRoute type, then we will create a new ParentRouter for a website full of ParentRoutes . Here is my simple ParentRouter type:
struct ParentRoute{T <: Toolips.AbstractHTTPRoute} <: Toolips.AbstractHTTPRoute
path::String
page::Function
pages::Vector{T}
end
Now I will add a route! function for a Vector of Parent routes.
function route!(c::AbstractConnection, routes::Vector{<:AbstractParentRoute})
end
If the target contains a single slash we will route it immediately to that page, but if it is larger we will prepare the target before calling the head and making the same call
function route!(c::AbstractConnection, routes::Vector{<:AbstractParentRoute})
target = get_route(c)
n_slashes = count('/', target)
target = split(target, "?")[1]
if n_slashes < 1
if ~(target in routes)
route!(c, routes["404"])
return
end
route!(c, routes[target], target)
else
split_target = split(target, "/")
end
nothing::Nothing
end
function route!(c::AbstractConnection, routes::Vector{<:AbstractParentRoute})
target = get_route(c)
n_slashes = count('/', target)
target = split(target, "?")[1]
if n_slashes < 1
if ~(target in routes)
route!(c, routes["404"])
return
end
route!(c, routes[target], target)
else
split_target = split(target, "/")
head = "/" * split_target[2]
if ~(head in routes)
route!(c, routes["404"])
return
end
route!(c, routes[head], target)
end
nothing::Nothing
end
Finally, we route! the individual ParentRoutes with another route! Method . This one is much more simple.
function route!(c::AbstractConnection, route::ParentRoute, target::AbstractString = route.path)
if target == route.path
route.page(c)
else
route!(c, route.pages)
end
nothing::Nothing
end
Finally, i’ll make a function for building our ParentRoute .
function parent_route(f::Function, path::String, provided_routes::Toolips.AbstractHTTPRoute ...)
routes = [provided_routes ...]
if length(routes) == 0
routes = Toolips.AbstractHTTPRoute[]
end
ParentRoute{typeof(routes).parameters[1]}(path, f, routes)
end
Now to test our addition in our test Module by aggregating our routes:
API_route = ToolipsAPIRouter.parent_route("/api", friends, adder_r, post_and_age) do c::AbstractConnection
write!(c, "welcome to the API")
end
main = ToolipsAPIRouter.parent_route("/") do c::AbstractConnection
write!(c, "my main website")
end
err = ToolipsAPIRouter.parent_route(Toolips.default_404.page, "404")
export err, API_route, main

A perfect execution!
closing thoughts
I am glad I was able to get through this project today and I am super happy with the results. Not only did we build a super convenient system for managing APIs, but we also created a unique parent system that really expands the capabilities of Toolips . With a bit more advanced work, this could effectively provide a future wherein a proxy and a web-server are running within the same server.
Both of these are awesome additions, and I am certainly considering releasing some packages to share these — might as well, right? I already wrote it. To be a package, though, also means to document, to test, to maintain, to eventually provide on ChifiDocs . It is always much more work than it seems. We will see what I or anyone else wants to do with the code, if anything. Maybe this will all pay off whenever I need to build complicated APIs in the future. Thank you all for reading, I will close out this piece with a link to the source:
메타데이터
- post_id
- 8e733daaba94
- slug
- finishing-my-api-routing-system-with-toolips-8e733daaba94
- url
- https://medium.com/chifi-media/finishing-my-api-routing-system-with-toolips-8e733daaba94
- canonical_url
- https://medium.com/chifi-media/finishing-my-api-routing-system-with-toolips-8e733daaba94
- author_url
- https://medium.com/@emmaccode
- status
- ok
- fetched_at
- 2026-06-24 13:29:15