Aloe Express is a simple yet powerful Web server module that's been specifically designed for use in Xojo console apps. It provides a foundation on which you can develop all types of Web solutions, from apps and sites, to APIs and microservices.
You can think of Aloe Express as a "black box" that receives an incoming request and makes it available to you so that you can evaluate and respond to it. What's nice about Aloe Express is that you don't need to know what's happening inside that "black box." (But if you're curious, click here.) All you need to do is write code that evaluates the request and generates a response.
At the heart of every Aloe Express-based app is an instance of the AloeExpress.Server class. You'll typically create an instance of the Server class in your app's Run event handler, where you'll configure it and start it.
In the example below, in the app's Run event handler, we're creating an instance of the AloeExpress.Server class and starting it.
If you were to run the app, you'd see something like this.
The Aloe Express server is ready to go. It's listening on port 8080, with a minimum of 3 sockets, and it is configured to create up to 7 additional sockets if necessary. (We'll talk about ports, sockets, and configuration options in a future tutorial.)
When Aloe Express receives a request, it creates an instance of the AloeExpress.Request class. The Request class has been designed to make it as easy as possible for you to evaluate a request. It provides access to a request's method, the requested path / endpoint, HTTP request headers, cookies, query parameters, and more.
Attached to the Request is an instance of the AloeExpress.Response class. The Response class makes it incredibly easy to specify a response status, headers, content, and cookies.
When a request is received by Aloe Express, it hands the Request instance off to an app-level method named RequestHandler. That's where you come in. You write code that evaluates the request and responds to it.
Suppose that regardless of the request, you always want to return a simple "Hello, World" response.
At the App-level, you'd create a method named RequestHandler, with a single parameter: Request As AloeExpress.Request. Aloe Express will pass incoming requests to this RequestHandler method for processing.Here's what a RequestHandler method would look like in order to send back the "Hello World" response.
As you can see, all that we need to do is set the content of the response, which we can do by setting the Request.Response.Content property.
If you were to send a request to the app via a browser, you'd see something like this.
Admittedly, that's not very exciting. But it's a start. And you have to admit, it may very well be the easiest, fastest "Hello World" example ever.
Aloe Express was originally designed for developing Web APIs and microservices. As you might expect, Aloe Express makes it very easy to return JSON-encoded responses. Let's look at an example.
First, we're creating a JSON object (using the Xojo JSONItem class), and setting a few properties. Next, because we're returning JSON text, we need to specify the response's content type. We're doing that using an Aloe Express helper function called "MIMETypeGet," which maps a file extension to the correct MIME type. (You no longer have to try to remember or lookup MIME types.) And finally, we're setting the response content by using the JSONItem's ToString property, which creates a string representation of the JSON object.
If you were to make a request to the app, you'd get a response that looks like this.
Notice that the response's Content-Type header is set correctly (to "application/json"), and that the content is the JSON string that we expected.
Note: The security-related headers mentioned in this section are no longer defaults. However, they can easily be set using the Response.SecurityHeadersSet method.
In that last example, you may have noticed that the response included a number of HTTP headers. Some of them are required and helpful, but several of them really only apply when you're developing Web apps and sites. For example, the Content-Security-Policy header, the Referrer-Policy header, the Strict-Transport-Security header, and so on. (Those default headers are set by Aloe Express to help improve the security of Web apps and sites.)
Suppose that we wanted to remove those headers, and maybe add an additional custom header as well. Here's what the RequestHandler method would look like.
And here's the response.
Notice that in the RequestHandler method, we added code to remove a few headers and add a new one. The Response.Headers property is actually a Xojo.Core.Dictionary. We can use its Remove method to remove entries, and the Value method to add a new entry. (In this example, we've added a X-Powered-By header to the response.) Earlier, we used the Value method to change the Content-Type header, which Aloe Express defaults to "text/html."
In the previous examples, we've returned the same response regardless of the request. Normally, you'd want to evaluate the request and respond to it accordingly.
For example, suppose that you want to return different content depending on the URL that was used to make the request. To get easy access to a request's URL, you can use the Request.Path property.
Here's what the responses would look like, depending on the URL used.
The Request class also provides a PathComponents property. PathComponents is an array of strings, where each string represents a component of the request path. For example, if the request is made using URL "/star-trek/captains/kirk," the PathComponents array would consist of three strings. The string at index 0 would be "star-trek." Index 1 would be "captains." And so on.
Like the Path property, the PathComponents property can also be helpful when it comes to evaluating and routing a request. For example...
Another Request property that can be helpful when processing and routing requests is the Method property. It's especially helpful when you're developing RESTful Web APIs and microservices. For example...
Let's take another look at one of the earlier examples.
This RequestHandler works well if the request URL is "/a" or "/b." However, if a different URL is used, or if the request is for the Web root, then the response will be empty - and worse, the response's HTTP status code will be 200, which indicates that everything was ok with the request. (Aloe Express sets the Response.Status to "200 OK" by default.)
In those cases, what we really want to do is return a "404" status code, which indicates that the requested resource wasn't found. Here's how you would do that.
If the Request.Path isn't supported, the response's Status property is set to "404 Not Found," and the content is set to reflect this. Here's what the response would look like.
Another way to return a 404 response is to use the Response.Set404Response method. You simply pass the method the request's headers and path, and the method will generate an Apache-like 404 response content and set the status for you. For example...
Here's what a 404 response would look like.
Aloe Express really shines when it comes to generating dynamic responses. However, there may be times - especially when you're developing Web apps and sites - when you'll want to serve up static files (such as images, stylesheets, and so on).
The Request.MapToFile method makes serving up static files very easy. In fact, all you have to do is call the method and Aloe Express will take it from there. For example...
The MapToFile method attempts to map the requested path to a file on the disk. By default, it looks in a folder named "htdocs" that is positioned in the parent folder of the app itself. (You can specify an alternative location using the Request.StaticPath property, which is a Xojo FolderItem.) The method will "walk" the request path and try to replicate that as it walks the folder structure.
If the MapToFile method is successful, it will also try to set the response's Content-Type header for you by mapping the file's extension to a MIME type. It does so using the Aloe Express "MIMETypeGet" helper method.
If the attempt to map the request to a static file is unsuccessful, the MapToFile method handles that as well. It will use the Response.Set404Response method (which we discussed earlier) to return a standard 404 response.
Aloe Express also provides an easy way for you to log HTTP requests. The Logger class generates logs in the industry standard Extended Log File Format, which can be used to analyze traffic and usage. One of the nice things about the Logger class is that it handles the logging on its own thread, so the write operation doesn't have a negative impact on your app's response time.
Here's an example of the Logger class being used to map requests.
By default, the Logger class writes logs to a "logs" folder that is located in the parent folder of the app itself. You can specify an alternative location using the Logger.Folder property (which is a Xojo FolderItem.)
Here's an example of what a log file looks like.
We've covered a number of Aloe Express's features, and yet we've really only scratched the surface. Aloe Express also provides support for cookies, managing sessions, caching, and more. We'll cover those topics in future tutorials.
In the meantime, you can learn about those features by exploring the demos that are included in the Aloe Express Demo app.