Developing a simple app with Merly.jl

In less than 10 minutes

Photo by James Harrison on Unsplash

Merly.jl is a micro web framework, written in Julia. It allows you to build back-end API applications and microservices, easily and quickly.

Installation

(@v1.5) pkg> add Merly

If for some reason you have trouble getting the latest version you can use these commands.

using PkgPkg.Registry.add (RegistrySpec (url = 
“https://github.com/JuliaRegistries/General"))
Pkg.update()Pkg.add (Pkg.PackageSpec (; name = “Merly”, version = “1.0.2”))

Programming

Let’s define the information we need to collect for each animal

TypeName

We are going to create a structure, which will allow us to create the custom type called Animal

mutable struct Animal
type :: String
name :: String
end

To store our Animal data, we will use a dictionary that will have an integer key as a key, which will function as an ID for our data.

ANIMALS = Dict {Int, Animal} ()

The value of the ID must be increased each time it is used, so we will create a wrapper for the integer, which will allow defining the variable as a constant.

const NEXT_ID = Ref (0)

We will also create a function called getNextId, which will increase the value of NEXT_ID by one each time it is executed.

function getNextId ()id = NEXT_ID []
NEXT_ID [] + = 1
return id
end

Now, we are going to create the route that allows us to register a new animal in our application. We will define the route “/ createAnimal” with the http POST verb, the function linked to this route will receive an object of type json, which will include the necessary data for the registration of our animal, which are type and name.

Since we will receive this data as text strings and we will have to convert them to a JSON object compatible with Julia, we will define a function that allows the conversion of string to JSON, which we will call: tojson

function tojson (data :: String)
return JSON.parse (data)
end

And we will add it to Merly, so that every time it receives data with the “application / json” header, it executes the tojson function, to process the data automatically.

formats [“application/json”] = tojson

So, we create the route with the @route macro, within it we will create a new ID, we will retrieve the data from the body of the HTTP request to later add the new Animal type data to our dictionary and return the new value of our object with its corresponding ID and the HTTP creation code.

Do not forget that we must pass the data defined in the main program and that we will use in the function associated with the route, such as the JSON library, the ANIMALS dictionary, the getNextId function, and the Animal structure.

@route POST "/createAnimal" (;JSON=JSON,ANIMALS=ANIMALS,getNextId=getNextId,Animal=Animal) beginid = getNextId()
ANIMALS[id] = Animal(request.body["type"],request.body["name"])
info=Dict()
info["id"]=id
info["type"]= request.body["type"]
info["name"]= request.body["name"]

body = JSON.json(info)HTTP.Response(201
, HTTP.mkheaders(["Content-Type" => "application/json"])
,body= body)
end

Now we are going to recover the data of all the animals registered in our application. For which we will define the route “/ getAnimals” with the HTTP GET verb, which will return the ANIMALS dictionary as a JSON object and for the browser to interpret it as such I will add the header “Content-Type” with the value “application / json “.

@route GET "/getAnimals" (;JSON=JSON,ANIMALS=ANIMALS) beginHTTP.Response(200
,HTTP.mkheaders(["Content-Type" => "application/json"])
,body=JSON.json(ANIMALS))
end

If now I want to visualize the data of a single animal, I will have to do it through its ID, so in the route I will pass that value and, in the application, I will indicate it through: id, in this way it will allow me to retrieve the value of the ID thanks to the dictionary params belonging to the request structure. Once the application receives the ID, the value will be converted to an integer and the data stored with that key value will be returned as json. Similarly, the “Content-Type” header will be added with the value “application / json”.

@route GET "/getAnimal/:id" (;JSON=JSON,ANIMALS=ANIMALS) beginid = parse(Int,request.params["id"])HTTP.Response(200
,HTTP.mkheaders(["Content-Type" => "application/json"])
,body=JSON.json( ANIMALS[id])
)end

To update the data of a previously registered animal, we will use the HTTP PUT verb and the route will be “/ updateAnimal /: id”, in the same way as in the previous case we must specify in the route the ID of the value we want to update, a once with the ID converted to integer, we will take the new data of the animal from the body of the request and we will use it to create a new data and assign it to the previously indicated ID.

@route PUT "/updateAnimal/:id (;JSON=JSON,ANIMALS=ANIMALS,Animal=Animal) beginid = parse(Int,request.params["id"])
ANIMALS[id] = Animal(request.body["type"],request.body["name"])
HTTP.Response(200)end

Finally, to delete a previously registered animal we will use the url “/ deleteAnimal /: id” with the HTTP DELETE verb, which will also receive the ID of the animal that we want to delete, for which the function delete! it will be of use to us.

@route DELETE "/deleteAnimal/:id" (;ANIMALS=ANIMALS) beginid = parse(Int,request.params["id"])
delete!(ANIMALS, id)
HTTP.Response(200)
end

With all the routes defined we will set up the server on port 8086 and the ip 127.0.0.1.

start(host = "127.0.0.1", port = 8086, verbose = true)
$ julia appmerly.jl
[ Info: POST > /createAnimal
[ Info: GET > /getAnimals
[ Info: GET > /getAnimal/:id
[ Info: PUT > /updateAnimal/:id
[ Info: DELETE > /deleteAnimal/:id
[ Info: Listening on: 127.0.0.1:8086

We will test the application with api tester . These are the results.

createAnimal

source: own creation

getAnimals

source: own creation

createAnimal

source: own creation

getAnimals

source: own creation

getAnimal/ID

source: own creation

updateAnimal/ID

source: own creation

getAnimals

source: own creation

deleteAnimal/ID

source: own creation

getAnimals

source: own creation

CONCLUSION

If there are any errors in this article or you feel that improvements can be made, please let me know in the comment section, I really appreciate it!

Josue Acevedo Maldonado is a software engineer, currently working as a consultant.

Connect in LinkedIn.

Thank you for being part of the community!
You can find related content on the channel YouTube, Twitter, Twitch, Spotify, etc, besides the book Ensamblador X86.

Finally, if you have enjoyed this article and feel that you have learned something valuable, please share so others can learn from it as well.

Thanks for reading!

Amante de la tecnologia y con pasion en resolver problemas interesantes, consultor, y creador del canal de youtube NEOMATRIX. https://linktr.ee/neomatrix

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store