Bright and Dark sides of Darklang
Set up an API, datastore, or background worker in 10 seconds
Some time ago I stumbled upon a Darklang. A completely new approach to cloud-native apps.
- The quickest way to code a backend
- Set up an API, datastore, or background worker, in 10 seconds
- Build an entire backend in hours
- Tooling you expect
Sounds promising right? I wanted to test out how much of those promises are actually true. The entire IT industry is rather focusing around small incremental change. One element to improve. Small but right. Darklang approach is very different. They are trying to invent everything once again. Claiming that it is more straightforward and faster. Rather than combining all the levels of abstraction, they are trying to build all the pieces together upfront.
In the standard approach, we have git branches, code changes, unit & integration testing, PR, commits, pushes, code review, CI, CD, deployments, keys, artifacts, instances configs.
In the Dark approach, we just change the code and it’s alive!
Please note that at the moment of writing Darklang is still in the BETA phase and issues presented in this article might no longer be valid.
I tried to find some simple use-case and proceed with the implementation. I’ve got access to the BETA version of Darklang (since it’s not yet live). Ready? Let’s start.
Website monitoring tool
Project: The app is loading a list of websites from google spreadsheet. Producing summary with rows like: “Domain ggajos.com returned 200", “Domain unknowndomain.com returned 500”.
Now. Let’s paint it.
Forget about projects, files, and directories
Darklang is using “Canvas” instead of “Projects”. It emphasizes the freedom of creation. We don’t have to worry about the location of elements. We are looking at the element that we are building and the things around it. We can see the canvas name in the address bar. The link will open our canvas in the place where we left it. We also don’t need to save anything, it just works. Every change is immediately available in production. While it might sound scary, there is a bunch of mechanisms to avoid unwanted surprises.
Let’s start with the creation of a simple endpoint.
First deployment on Production
Try to imagine what would be the fastest way to do that? Try to recall what steps you need to perform in the framework you are using right now? How much boilerplate and redundant actions you need to perform?
Creating a new HTTP endpoint is one of the most trivial cases:
- 1. Click somewhere on the canvas.
- 2. Select “New HTTP Handler” option.
- 3. Select the name of the endpoint.
- 4. Select the verb.
- 5. Type the sample response.
- 6. Open the browser with the newly created endpoint by a single click.
- DONE
Wow, that was fast. Can we speed this up even more? Well, yes. On the first menu, we don’t have to pick anything. We can immediately start typing REST endpoint name (uri):
It’s insane how well hidden is the complexity of possible options. The UX here is outstanding. The change is available immediately online.
Providing a list of URLs to monitor
Now let’s prepare a list of our websites to check. I’m going to type a few webpages in spreadsheet.
We are going to access the spreadsheet via Google Sheet API. The required request is self-explanatory.
GET https://sheets.googleapis.com/v4/spreadsheets/ {spreadsheetId}/values/{range}
Let’s try to implement that call.
Loading data from a spreadsheet
Darklang provides class HttpClient
with a few methods to perform the HTTP calls. We are interested in HttpClient::get
method which is performing (suprise) a GET
call.
Ooops, we have PERMISSION_DENIED
reply from the API. It looks like we need to provide an API key. The second parameter of the HttpClient::get
is a query part. We can provide query args by passing a map like{ key: … }
:
What is again a really nice feature, is that we are able to see the response immediately. There is no need to execute any run button, compile anything, or wait for some action. It is really crazy fast way of prototyping! But the really neat feature is about to come.
Mind-blowing-friendly feature of dark: Autocomplete for dynamic JSON
This has to be scam right? How we can get the autocomplete for the JSON file if there is no definition or schema of the structure? How this can work if the structure of the JSON is completely dynamic? Well, it can:
Since code is executed immediately, the content of the JSON is parsed from the real response. Analyzed and fetched into autocomplete. It’s so simple, yet one of the most mind-blowing features. That’s not all. We can see the preview of the selected element while typing.
Ok, now let’s try to export a list of websites from the reply.
Functional programming
Dark is heavily functional, however, the syntax sometimes is a bit odd. Rather than mapping object like list.map(...
we need to reach out for static reference and pass the object as the first argument List::map list lambda
. I can understand some rationale behind it but even returning some element from the list is not just likelist[0]
but another static method List::getAt list 0
. When we add up everything together it is getting little less readable than expected (as in Java for example). The response from the google spreadsheet is a two-dimensional array (array of arrays). We need to extract the array. Below it’s a code that is extracting a single array from an array of arrays.
Now when we are able to list out websites, let’s try to actually fire the request and see the response code (that website is working fine).
Monitoring websites
We are going to use HttpClient::get
again and get the response.code
out of it. Our endpoint is returning now a list of response codes rather than websites:
Trivial String join
Let’s try to do some very basic operation. Concat the website along with the status code. Very simple, right?
Well, here things are getting clunky. The response code is Int
and the text is String
:
- There is an operator
+
which is able to concatInt
types, but cannot be used since types are different. - There is an operator
++
which is able to concatString
types but cannot be used as well, types are different. - There are no methods like
Int::toString
orString::valueOf
There is a simple method toString
that is coming from nowhere, just a public static method available for the operation. Can be used like toString number
and returns String
type. While it’s doing the job well, it feels like a little inconsistency (why it’s not part of some Commons::
?).
The text is finally concatenated. Changes are available immediately and we can see the responses of the websites.
Now let’s try to add a new website and see the result.
Great! The happy path is done. Now let’s add some not existing domain to see the result.
Ooops. There is an error.
Error rail
How does the error handling look like? Darklang introduce mechanism called Error Rail
The error rail allows you to keep writing code along the “happy path,” without stopping to handle errors. This is based on Railway Oriented Programming and the UI elements are unique to Dark.
In short, instead of try/catch blocks, errors are returned from functions and handled via pattern matching or if/else blocks. I wanted to present it here as well but there was little surprise. This feature is a little buggy now, so it’s not possible to catch the error.
Bright Side of Darklang
It’s the biggest paradigm shift that I’ve seen for quite some time. Darklang is finally something that is not built as abstraction layer over all other layers of abstraction. Autocomplete or live preview feels like the application is running while typing. Working with requests and payloads is just insanely easy.
Dark Side of Darklang
The code editing is really awkward sometimes. The idea is that it should be hard to make a mistake or write down a code that is incorrect, but actually sometimes it’s hard to write it at all. Even removing part of the text (code) is difficult. I had to copy the code out from the browser to notepad, edit outside and paste it back. The structure of the code is very flat, therefore I cannot see how to write something bigger than a couple of methods/functions.
I’m judging now something which is still in BETA phase, so I will stop :). The work done by Darklang team is really outstanding. Fingers crossed how the project is going to develop over time.