Introduction
We are starting an adventure: we are going to build a great-outstanding-marvelous application using the Crystal language!
But, since these are our first steps using the Crystal language, maybe we could start with a first simple app? 🤔 Yeah! It sounds good! So, this is the goal for this post: 3 steps for creating a simple app using Crystal! 🚀
1, 2, 3 … Hold it! We are assuming that you already have installed the Crystal language. But, what if you didn't? 😱
Well, in that case here it is step 0:
- Go to the Crystal language site and click on Install. There you'll find all you need to install the language compiler for your platform ... don't worry, we'll wait for you ...
and another step 0 😝:
- In the overview section, you will find some great examples if you didn't use Crystal before.
⏰a few minutes later
Are you ready? Great! Let's start!
Step 1: init
is the magic word
So, first things first: assuming that our app is called my_app
(if you can think of a better name, go ahead and rename it! 🙃) then we create the application using the same Crystal's command line, like this:
$ crystal init app my_app
And Crystal will reply:
create my_app/.gitignore
create my_app/.editorconfig
create my_app/LICENSE
create my_app/README.md
create my_app/.travis.yml
create my_app/shard.yml
create my_app/src/my_app.cr
create my_app/spec/spec_helper.cr
create my_app/spec/my_app_spec.cr
Initialized empty Git repository in /great_projects/my_app/.git/
Perfect! We have the project with the Git repository already initialized and with a basic .gitignore
(thanks Crystal! ❤️)
In the folder my_app/src/my_app.cr
we have the entry point to our application. Although we may use other file, it is a standing point to start building our app.
Step 2: Hello world database!
Not the Hello World example! With step 1
we have a new Crystal App ready to grow! So let's continue with a more interesting example ... maybe we could connect to a database? Yeah! Let's do that!
We'll be using a MySQL database, It won't be necessary to install the database in our computer, instead we could use a Docker container! Here's the docker-compose.yml
file:
version: '3'
services:
db:
image: mysql:8.0.17
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
container_name: crystal_db
ports:
- 3306:3306
volumes:
db:
Great! With this, we may start the container and have a MySQL database ready for us to use!
Let's start the container:
$ docker-compose up
If it's all good, then the response from docker should end with something like this:
crystal_db | Socket: '/var/run/mysqld/mysqlx.sock' bind-address: '::' port: 33060
Now, using our favourite database tool (in my case I'm using TablePlus), we may connect to the database using this configuration:
host: 127.0.0.1
port: 3306
user: root
password: root
And last (but not least) we will create a new database for our project called crystal123_db
CREATE DATABASE `crystal123_db`;
USE `crystal123_db`;
Step 3: (Actually) using the database from our app!
And here we are, the final step! We will need the corresponding MySQL-connector in order to use the database from our Crystal app.
First, we need to add the mysql-shard in our application's shard.yml
file, like this:
dependencies:
mysql:
github: crystal-lang/crystal-mysql
And then, we install all the dependencies with:
$ shards install
Shards will reply:
Fetching https://github.com/crystal-lang/crystal-mysql.git
Fetching https://github.com/crystal-lang/crystal-db.git
Installing mysql (0.10.0)
Installing db (0.8.0)
Note: Shards is the Dependency manager for the Crystal language.
Now, let's try to connect to the database! (remember we called the database: crystal123_db
... a great name if you ask me 😎) And, since we are there, we will create a new table called bank_accounts
(with to columns: name
and amount
)
# my_app.cr
require "mysql"
db = DB.open "mysql://root:root@localhost/crystal123_db"
db.exec "drop table if exists bank_accounts"
db.exec "create table bank_accounts (name varchar(30), amount int)"
Let's run the code using Crystal's command line:
$ crystal ./src/my_app.cr
Go to the database ... yes! The table bank_accounts
was created!!
And for the same price, let's add 2 rows to the table. Here is the final version of my_app.cr
:
# my_app.cr
require "mysql"
db = DB.open "mysql://root:root@localhost/crystal123_db"
db.exec "drop table if exists bank_accounts"
db.exec "create table bank_accounts (name varchar(30), amount int)"
# first row
db.exec "insert into bank_accounts values (?, ?)", "John", 100
# second row
db.exec "insert into bank_accounts values (?, ?)", "Sarah", 250
We run the application:
$ crystal ./src/my_app.cr
Let's check the database and ... yes! Now we have the table bank_accounts
created and with 2 rows! We did it! 🎉
Farewell and see you later
We have reached the end of this first journey. To recap:
- we have initialized a Crystal application using the command line.
- we have installed a database (actually a container with the database)
- and finally we have use the database from our Crystal application!
Hope you enjoyed it! Until the next Crystal
adventure!😃
References:
- Using the Crystal compiler
- Using a database with Crystal.
- The shards command
Top comments (6)
Why would a language assume you were using one particular type of VCS? There's opinionated, and there's presumptive. I've never tried Crystal, but that bit puts me off it.
Hi Ben! Thanks for reading and comment! I understand your point of view, but I think that the language gives us an initialized repository just to make our life easier. Git is a free and open source VCS and one of the most used, so I don't think the language is doing any harm. In case we don't want to use it, we can remove (
rm
) the repository folder and that's it!Perhaps in the future there are more options (?) 🤷♂️
Anyway, I hope that that bit didn't put you off it and you keep trying the language! 😃
Git is the backbone for Crystal's dependency manager shards. If you want to make your project available in the Crystal ecosystem, there's no way around git.
So it's not just an opinionated choice but a functional requirement. Of course, when shards supports other distribution systems as well, this might need a revisit.
Crystal is open source, feel free to fork and add support for other VCS's - git's popular right now and so they went with that as the default. You're not forced to use the commands and you can easily delete the .git folder if you do.
I'm aware you can remove it - I just think it's a bad practice to include things that aren't part of the purpose of the product. Facebook is popular, but I don't feel like including a facebook oauth library in my calculator app.
It seems like a really bad idea to me - it makes me wonder what other stuff they use magic for.