From PHP to Rust: Migrating a REST API between these two languages. (Part I)
Migrating a Rest API implemented in hexagonal architecture
Disclaimer
Before beginning, I want to say that I'm a huge fan of PHP
for several years. This not only allowed me to create great applications but also keeps the food on my table <3.
However, Rust
is gaining traction among the developer community. It's not for nothing that it's the most loved
programming language in the last 7 years
in Stackoverflow's Developer Survey
(details here). With this blog post, I want to try and show you the difficulties for a PHP
developer to learn Rust
with a practical example: the migration of a single API endpoint from PHP to Rust
.
What's RUST Language
Originally made as a C-Language
replacement, Rust
rapidly evolved not only to build software systems (operating systems, IoT, and AI)
but with the big community, the web frameworks begin to grow in the ecosystem
Why Rust
:
Blazingly fast and memory-efficient. With no runtime or garbage collector, it can power performance-critical services
A strong typed system and ownership model that guarantees memory-safety and thread-safety programming, enabling you to eliminate many cases of bugs at compile-time
Great documentation, a friendly compiler with useful error messages, top-notch tooling and much more.
The most known web framework is called Actix-Web
(more here) , and it is considered one of the most performant web frameworks available on the market
, capable of serving 552K requests per second
. (the benchmark can be viewed here)
The Application
If you read my previous blog post, I always have a "demo application"
to use in all my tutorials: the "Availability API"
. This application is far from simple but it contains the implementation of a minimum web application nowadays (Rest API, DB Access, Hexagonal Architecture design, etc).
The architecture of the infrastructure is not important here but since we use a k8s cluster agnostic, we can reuse it here for demonstration purposes.
The Migration
As the first step, we want to write the web server and configure the web server using the actix-web framework
. This will include setting the routing and the controller to receive and respond to requests.
File Structures
As we said before, the availability API
was designed with a hexagonal architecture in mind, so we want to reach the same goal using Rust
. Let's see how it compares with PHP.
Rust main
entrypoint
In Rust
you use main.rs
. This is equal to bootstrapping in PHP
. In this file, you have a main()
function, which is mandatory for any Rust
application to work just like Java
or Typescript
Main.
Here how my main.rs
the file looks like. Remember, that I'm using using actix-web
framework, so the "bootstrapping"
of the web server will be through the actix-web
framework.
You also have the availability-controller
. This will ask third party API's
and databases
if it's available.
Note that PropertyAvailabilityRequest
is a DTO
with a series of ValueObject
that validates itself, so in case of an invalid request
body
, and serialized JSON
error is returned to the client.
Compile and Run
Now let's compile and try to run this first step:
cargo build && cargo run
Now we're ready to test our first very basic endpoint, the response must be equal to the request that we send to the API.
curl --location --request POST 'http://localhost:8080/v1/property/availability' \
--header 'Content-Type: application/vnd.api+json' \
--header 'Accept: application/vnd.api+json' \
--data-raw '{
"requestDates": {
"checkin": "1956-06-29T02:09:38.752Z",
"checkout": "1977-01-17T15:39:47.465Z"
},
"pax": [
{
"adults": 2,
"childs": 1
}
]
}'
And at least for this first part, we can migrate an endpoint from PHP
to Rust
. We have a lot of work to do regarding the database connection, event dispatching and other kinds of stuff. In the next chapter, we will add some kind of middleware to add custom headers, database connection and so on.
Thank you for reading!
Support Me
If you like what you just read and you find it valuable, then you can buy me a coffee by clicking the link in the image below.