Learn more about our current job openings and benefits of working at FSL.
Detailed reviews and feedback from past and current clients.
Get to know the Management Team behind FullStack Labs.
Our step-by-step process for designing and developing new applications.
Writings from our team on technology, design, and business.
Get answers to the questions most frequently asked by new clients.
Learn about our company culture and defining principles.
A high level overview of FullStack Labs, who we are, and what we do.
A JavaScript framework that allows rapid development of native Android and IOS apps.
A JavaScript framework maintained by Facebook that's ideal for building complex, modern user interfaces within single page web apps.
A server side programming language known for its ease of use and speed of development.
A lightweight and efficient backend javascript framework for web apps.
An interpreted high-level programming language great for general purpose programming.
A JavaScript framework maintained by Google that addresses many of the challenges encountered when building single-page apps.
A JavaScript framework that allows developers to build large, complex, scalable single-page web applications.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
View a sampling of our work implemented using a variety of our favorite technologies.
View examples of the process we use to build custom software solutions for our clients.
View projects implemented using this javascript framework ideal for building complex, modern user interfaces within single page web apps.
View projects implemented using this framework that allows rapid development of native Android and IOS apps.
View projects implemented using this backend javascript framework for web apps.
View projects implemented using this high-level programming language great for general purpose programming.
View projects implemented using this server side programming language known for its ease of use and speed of development.
We have vast experience crafting healthcare software development solutions, including UI/UX Design, Application Development, Legacy Healthcare Systems, and Team Augmentation. Our development services help the healthcare industry by enhancing accessibility, productivity, portability, and scalability.
We offer a range of custom software development solutions for education companies of all sizes. We're experts in Education Software Development and specialists in enhancing the learning experience across web, mobile, and conversational UI.
We're experts in developing Custom Software Solutions for the Logistics Industry. Our work offered a whole new and more efficient way for Logistics companies to manage their crucial operations.
We partner with various construction industry organizations to build custom software development solutions. Our Construction Software Development Services allow construction companies to manage projects, resources, and documentation.
We have vast experience crafting healthcare software development solutions, including UI/UX Design, Application Development, Legacy Healthcare Systems, and Team Augmentation. Our development services help the healthcare industry by enhancing accessibility, productivity, portability, and scalability.
We offer a range of custom software development solutions for education companies of all sizes. We're experts in Education Software Development and specialists in enhancing the learning experience across web, mobile, and conversational UI.
We're experts in developing Custom Software Solutions for the Logistics Industry. Our work offered a whole new and more efficient way for Logistics companies to manage their crucial operations.
We partner with various construction industry organizations to build custom software development solutions. Our Construction Software Development Services allow construction companies to manage projects, resources, and documentation.
Learn more about our current job openings and benefits of working at FSL.
Detailed reviews and feedback from past and current clients.
Get to know the Management Team behind FullStack Labs.
Our step-by-step process for designing and developing new applications.
Writings from our team on technology, design, and business.
Get answers to the questions most frequently asked by new clients.
Learn about our company culture and defining principles.
A high level overview of FullStack Labs, who we are, and what we do.
A JavaScript framework that allows rapid development of native Android and IOS apps.
A JavaScript framework maintained by Facebook that's ideal for building complex, modern user interfaces within single page web apps.
A server side programming language known for its ease of use and speed of development.
A lightweight and efficient backend javascript framework for web apps.
An interpreted high-level programming language great for general purpose programming.
A JavaScript framework maintained by Google that addresses many of the challenges encountered when building single-page apps.
A JavaScript framework that allows developers to build large, complex, scalable single-page web applications.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A dynamic programming language used in all sorts of web and mobile applications.
A cross-platform programming language designed to run robust applications on any device.
A UI toolkit used to build natively compiled applications from a single codebase.
A functional programming language that’s ideal for scalability, maintainability, and reliability.
A Customer Relationship Management (CRM) platform that seamlessly integrates with your business operations.
A high-performance programming language that makes it easy to build simple, reliable, and efficient software.
View a sampling of our work implemented using a variety of our favorite technologies.
View examples of the process we use to build custom software solutions for our clients.
View projects implemented using this javascript framework ideal for building complex, modern user interfaces within single page web apps.
View projects implemented using this framework that allows rapid development of native Android and IOS apps.
View projects implemented using this backend javascript framework for web apps.
View projects implemented using this high-level programming language great for general purpose programming.
View projects implemented using this server side programming language known for its ease of use and speed of development.
Today, there are so many different tech stacks available that it can be hard to commit to just one. I've been researching a ton of different languages and frameworks to try and find a combination that I really like. The winner: Elixir and Phoenix.
Elixir is a fun language that is really comfortable to write and packs a lot of really cool features that are actually useful in real-life situations. Phoenix is a web framework that provides a clear path for development while still allowing for flexibility.
In this article, I want to give a high-level overview of concepts involved in building a Phoenix app so people interested in Elixir and Phoenix can determine if it’s for them.
Elixir is a programming language that was created by José Valim, a member of the Ruby on Rails Core Team. Although Elixir is a young language, it has a very rich ecosystem and I haven't had difficulty finding packages to accomplish common goals.
Elixir is a compiled language but it runs on the Erlang VM or BEAM. Erlang was originally designed for telecom applications; this means Erlang was designed with real-time, highly available, fault-tolerant, and concurrent systems in mind, which is great for Elixir.
However, if you come across something that you can't accomplish in Elixir, you always have the option to break out to the Erlang environment where you have an entirely different ecosystem of features and packages. This is something that should probably only be used as an escape hatch and I have not delved into this particular feature myself; you are on your own if you try this, but it's nice to know the option is there.
Most of the code you write in Elixir is actually run within processes; this isn't immediately apparent when you first start building. It's important to note that these are not OS processes but lightweight Erlang processes that are more akin to threads. Each process is an encapsulated bit of code that manages its own state and communicates with the rest of the app by sending and receiving messages.
All of these processes are managed in a supervision tree. There is a supervisor that orchestrates all of its subprocesses. This idea of using processes and supervisors to manage trees is what gives Elixir its fault-tolerant quality. If a single process crashes, only that one crashes and the supervisor can determine whether it should restart it.
Phoenix is a modern web app framework built for Elixir. It is highly opinionated but in a good way. You probably think when hearing a framework is “highly opinionated” that it's going to have great support for the usual needs in building an API, but as soon as you need to break out and do something unusual you have no choice but to rely on weird hacks and ugly code. With Phoenix, I haven’t seen this problem. Its architecture lets you weave in any code you need with ease.
Aside from this, Phoenix follows a general MVC architecture with just a few caveats. Rather than stopping at the number of abstractions that yield an intriguing acronym, they took it just a little bit further. At first, this may seem overly verbose and adds a ton of boilerplate code; but as your app grows you'll be grateful that your code is automatically organized in a manner that makes for easy refactors and extending.
Elixir relies on a library called Plug to coordinate changes. Essentially, Plug allows you to define small functions or modules that take in a data structure – typically a connection – and returns it with slight modifications. This means that every request to your Phoenix server essentially passes through a series of functions until all the necessary data is available to send as a response.
As you dig around the code in a Phoenix app you'll see a lot of random words being used as if they are keywords; they are a feature of Elixir that generates more code in the form of macros. At first, I was a little worried by the "magic" that these macros provide, but used tastefully, they can be a great help and reduce a lot of complexity. Macros are another feature I haven't had time to take a deep dive into, but I can see how they are helpful (I can also see how they could be extremely dangerous).
As mentioned earlier, Phoenix follows an MVC pattern, so the flow through your app should be familiar:
Endpoint -> Router -> Controller/Context -> View -> Template
In order to follow along, we'll spin up a Phoenix app. This requires Elixir installed on your machine. For the sake of brevity, I will not include the steps to get Elixir installed, but I recommend managing your installation with asdf. The website thinkingelixir.com has a great article that explains it: https://thinkingelixir.com/install-elixir-using-asdf/
Once you have it installed, we can use mix to install the Phoenix app generator:
-- CODE language-bash keep-markup --
$ mix archive.install hex phx_new 1.5.1
We can now generate a new Phoenix project by running:
-- CODE language-bash keep-markup --
$ mix phx.new anatomy_app
Finally, we can move into our new project directory and start our server:
-- CODE language-bash keep-markup --
$ cd anatomy_app
$ mix phx.server
With our new project set up, onward to the architecture!
When a connection is received by a Phoenix app, the first stop is the endpoint. The endpoint is just a Plug that manages a few concerns:
If we open up the file that defines our endpoint, lib/anatomy_app_web/endpoint.ex, we see that the file uses the Plug and socket macros to define the usual things a web server needs to do: setting up sockets, handling static content, managing session, and forwarding the connection to the router.
Open the file lib/anatomy_app_web/router.ex. Much like the endpoint file, it’s using macros to create different Plug pipelines to pass the request through before passing to the controllers. The router is a great place to make any updates to your connection that you will need downstream. Since the router is deciding which controller to forward the request to, it's a great place to include your authorization and authentication code.
Looking at the file, we see several macros:
Once the request makes it through the appropriate pipeline of Plugs for its scope it is passed along to the controllers.
The controller is where we see the “opinionated” structure that Phoenix enforces. Rather than having a controller that manages reading, updating, collecting, AND organizing, it splits these responsibilities. This isn't really a revolutionary idea and you've probably seen it done with things like an ORM, where we write controllers that dispatch to models, services, etc. In Phoenix, we have contexts.
Contexts are logical groupings of our data that manage data validation, access, and making updates to storage. To make this process easier, Phoenix uses a library called Ecto. Ecto gives us some macros that map the schema of our data structures to tables in our database. It also handles changes made to our database using a construct known as a changeset. Essentially, changesets allow us to group the changes that take place in different requests and run validations before committing them. Again, this seems like an unnecessary abstraction, but being able to scope the changes gives us a lot of power and is really useful in eliminating those that could break our schema/app. The full power of Ecto and changesets are beyond the scope of this article; however, the docs for Ecto are pretty thorough and easy to understand: https://hexdocs.pm/phoenix/ecto.html
With our contexts in place, we can then use them in our controllers to gather/orchestrate data and pass along to views. The project we generated does not include any contexts, but they reside in /lib/anatomy_app. If we were to create an accounts context we would create the following files:
This is a hypothetical set up, but essentially lib/anatomy_app/accounts/user.ex defines a user context that manages reading and writing data, and lib/anatomy_app/accounts.ex uses this context to orchestrate data access/reading for the entire context. These can then be used in our controller for fetching and working with the data.
We were provided with a single controller in the project that we generated and it can be found at lib/anatomy_app_web/controllers/page_controller.ex. If we open this file up, we see it is very sparse:
-- CODE language-jsx keep-markup --
defmodule TestWeb.PageController do
use TestWeb, :controller
def index(conn, _params) do
render(conn, "index.html")
end
end
What’s happening here is we instructed Elixir to bring in all the functionality that Phoenix provides for controllers with the use statement. We then define a function index that takes a connection and passes it to the index.html template for rendering. If you’ll recall, back in our router, the index route was defined like this:
-- CODE language-bash keep-markup --
get "/", PageController, :index
Knowing the contents of our controller, this statement should make a little more sense. All it is saying is: “Forward any GET requests to ‘/’ to the PageController’s index function.”
Just like with contexts and controllers, Phoenix splits our code for handling views into separate pieces. For the most part, views will be pretty sparse; Phoenix's naming conventions and "magic" remove a lot of the code. If you’re building a full web app with Phoenix, meaning you are using Phoenix's templating to generate a site, you will mostly have formatting and data preparation code. If you're building a JSON API, views are where you will do renaming and formatting.
For both a web app and a JSON API, we then pass the data from the views to a template to be rendered. Phoenix provides an HTML templating language that should be very familiar. Within our templates, we can access the connection and data we've accrued throughout our Plug pipeline. Phoenix templates are written much like components in React; each file maps to a certain view and handles displaying data for that page. The markup language is a little odd at first but becomes familiar pretty quickly. It also provides some nice features, such as links to easily weave the different parts of our application together.
When learning a new language or framework, it's very easy to find short, focused articles; however, I typically struggle with getting a high-level understanding of the different pieces and how they fit together. I wrote this comprehensive overview for people coming to Elixir and Phoenix to help them determine if they want to continue learning. I hope this helps!
We’d love to learn more about your project.
Engagements start at $75,000.