By now everybody has to know what Salesforce Lightning is, but how many of you have actually tried to develop something in Lightning? I know I didn’t until 6 months ago. Last december I thought to myself I should at least try it; cover the basics. And so I did.
The most obvious place to start is Salesforce Trailhead. It’s a great way of learning and of course earn some badges. Yet after Trailhead I was still not satisfied. Lightning kinda stuck on me so I was looking for a deeper understanding of the lightning component framework and how it would benefit our development process.
So by now I knew what Lightning was about, I knew the basics thanks to Trailhead and now it was time to kick it up a notch. In search of a good use case, I remembered the Visualforce Chess application we had developed at ABSI two years ago. Little eureka moment right there; I had just found my use case!
Why a chess application? That’s not a real business case!?
That’s true, yet let me tell you it’s so much fun to create and isn’t that the best way of learning? It’s also what Trailhead is all about: learning through gamification. Well perhaps I must admit I took the gamification part a bit too literal here. Nonetheless it’s a clear use case and it’s fun to do, besides how cool is it to tell people you have built a chess application in Salesforce.
And so Lightning Chess was born. A fully functional multiplayer chess game build with the Salesforce Lightning Component Framework.
We've had the opportunity to share this application at the Salesforce World Tour Amsterdam educating others on the use and design benefits of Lightning Components but I also want to share it here, for all of you who could not be there. Let’s start with a small demo:
In this blog we'll first have a look at this Lightning Chess application and then zoom in a little bit more on the Lightning component framework, how the application is build up and what the benefits are of the component based approach.
This is Lightning Chess
If you look it up in a dictionary you might come across the following description:
“A form of chess in which each move must be completed within a very short time, usually ten seconds.”
In this case though it’s not… Lightning Chess is an application build with the use of the Lightning Component Framework. It allows Salesforce users to challenge each other for a chess duel, just to prove who is the better chess player.
So we sit together in front of one computer and each player takes turns to make his move? Oh no, no, no. Each player can access the Lightning Chess application from his own device. From that point on he can challenge any user that is currently available!
So how was this achieved?
First of all we need the basics, a location to persist our game data. The obvious place to do this is of course the Salesforce platform. So the first step was to declare a data model and start creating those custom objects.
Next thing we need is a client to display our data. The client, as already mentioned above, is a Lightning application hosted on the Salesforce platform. The client contains the logic to handle all the user interactions and updates it receives from the server. Meaning it contains all the view logic.
Third step; we need a means to update our server side data. Of course Lightning provides this through Apex controllers. The client calls server side methods in order to persist the records with the view state.
Pretty standard so far, no?
Let’s put all this in an example:
- 1. The player wants to move one of his pieces to a new location.
- 2. He first undertakes the necessary steps in the UI.
- 3. The client will then inform the server that the player just made a new board move.
- 4. In the Apex controller we update the data model so that it reflects the most recent state of the client.
But wait a minute… what about that other person? The one I’m trying to beat in chess!? Rest assured he or she has not been forgotten.
And so there is a fourth step. In order to keep both clients in sync the Streaming API was added to the Lightning application. The Streaming API allows us to inform subscribers about changes in our data model.
Let’s take our previous example and add the last important step.
This last step is all about getting the correct state back to the subscribed clients.
All that was needed was to create a channel that sends out notifications to the subscribers when a new move has been created. As player 2 is also subscribing to this channel he will see that his client is updated with the new game state once he receives the notification.
And there you have it, a real time chess application where both Lightning clients are kept in perfect sync.
What is the Lightning Component Framework?
It’s not the intent here to give you a full description of the Lightning Component Framework. If you want a full and detailed description I bet there are numerous places where you can find this, for example the official Lightning reference.
Instead what we’ll do now is give a little overview of some key aspects in the Lightning Component Framework. In the following sections we’ll see what this means in terms of Lightning Chess and how it benefits the application.
Let’s get started.
Lightning uses a stateful client and a stateless server approach. This provides a more dynamic and faster user experience as the client is now responsible for maintaining its own view state. The server is only called when the client needs to access or store data.
The Lightning Component Framework allows us developers to create parts of the UI within Salesforce. These parts can range from full blown applications to just very small parts of the UI. As the name already suggests this is done in a component based fashion. The idea here is to split up your application into smaller components. Each of these components will then do what it’s supposed to do and only that.
A great way of looking at this is with one of the object oriented principles: ‘Single Responsibility’. Give each component a clear and single responsibility. By limiting the responsibility of one component you first of all allow it to be darn good at what it’s supposed to do. Second it allows for smaller and less complex components, which leads to more readable, maintainable and extendable code. And third, perhaps the most important one of all, it allows for more reusable components as you take one functionality and allow it to be used in many other components and this in a loosely coupled fashion.
Component encapsulation plays a big role. To put this simple, we only need to know what a component can do. A consumer of this component is not interested in how it does what it does. Instead each component will have a public facing side while its internals are kept to itself. Changing the internals of this component should not change its consumers, providing a loose coupling.
We’ve seen that the consumer of a component shouldn’t know about the internals of that specific component. The other direction is equally important. It should not matter for the component who is consuming it. But still the component might need a way to inform its consumer something happened. To support this Lightning provides an event driven architecture. This event driven approach allows your components to communicate in a loosely coupled fashion.
As a last point here I would like to mention something I’m pretty excited about: Object Oriented Programming with Lightning components. If we talk about OOP we can’t leave out inheritance of course. And yes Lighting allows for components to extend other components. This provides us a means to share functionality between different components. Additionally Lightning also contains Interfaces which allows us to program against an abstraction rather than programming against a concrete component.
Each of the above aspects will be explained in more detail in what follows next.
Lightning Chess building blocks
Who didn’t enjoy playing with Legos in their childhood? All those blocks with their different shapes and sizes. Put some of those blocks together and before you know it, you’ve just build a whole death star. You could compare Lightning with this. Only here you’re just putting components together. Instead of clicking them together you’re linking them up with events and handlers.
Lightning contains an out of the box component library that you can use to build your own components. You can also search the component exchange for components and if you don’t find what you need just build them from scratch. You might not have guessed it but that’s what I had to do. Can you imagine no chess components to be found anywhere?!
All jokes aside, let’s have a look at what makes Lighting Chess tick.
Remember I claimed that we have to divide our application in smaller components each with their own responsibility? Because you have to practice what you preach, here are the components used in Lightning chess with their respective responsibility:
- 1. General_Game_Component: Manage (start/finish) any type of game.
- 2. Chessboard_Component: Manage the state of the chessboard by handling location and streaming events taking chess logic into account.
- 3. Chessboard_Location_Component: Handle action events and render the correct state of his location based on these events.
- 4. Player_List_Component: Manage and display the online players and issue challenges.
- 5. Challenge_List_Component: Manage and display incoming challenges
- 6. Streaming_API_Component: Subscribe to Push Topics and convert streaming events into Lightning events
In the image above you can find the component composition. As you can see the main component is called the General Game Component. This component basically contains all other components that make Lightning Chess. Let’s now zoom in a little bit more on this component to give you an idea why it’s there and how it benefits us.
Open for extension
First of all the General Game Component defines the look and feel of the application. It structures all the other components. But that’s not the main purpose it’s there. Let’s take the example of how it was done initially; yes everyone has to learn and sometimes that means making mistakes…
The first version of Lightning Chess had no General Game Component. The Chessboard component was the top level component containing all other components. If we look at the above responsibilities the Chessboard Component would have: Manage the state of the chessboard by handling location and streaming events taking chess logic into account + Start/load a new chess game when the event is received. What I’m trying to show here is that at that point the Chessboard had too much responsibility. Not only was it managing the current game it was also starting new ones. When you’re developing it’s always better to stop and think ahead. Doing that I realised this was not the most flexible approach.
Let’s say I would like to add a checkers game and allow the user to choose between playing chess or checkers when they challenge another player? How could I ever achieve that when the chessboard was basically my controlling component? The answer is simple: it’s not possible…
So back to the drawing board to split those responsibilities. And so the General Game Component was created. This component dynamically creates a new component based on the event it receives. Just to put this in context with an example:
- 1. Player 1 challenges Player 2.
- 2. Player 2 accepts the challenge and this creates a new chessboard (server side).
- 3. Both players receive a notification through the Streaming API telling the client a new chessboard is created for them.
- 4. Our General Game Component will respond to this type of event and dynamically create a new component of type Chessboard.
What if I want to add support for another game? Well that’s simple we just extend, not change, the General Game Component to respond to a new event and load a different game component. Easypeasy.
Notice the loosely coupled approach here. The General Component doesn’t really know what component he is showing. The Chessboard component just functions on it’s own doing what it’s supposed to do without any direct interference of another component.
Let’s take a step back and play with some legos again. Remember those big boxes of lego you had as a child? All those blocks going in a huge box and when the time was right you would open the box and start building something new. The Lightning component framework is just like that. When developing in Lighting I believe it to be a best approach to single out those components that might be useful in other implementations. Once you’re done with them in your current implementation, just throw them in your big toolbox. When the time is right you will pick them up once more.
Needless to say that this can greatly improve your development process when done correctly.
Let’s take the example of the Streaming API Component.
We needed the Streaming API to be included in the Lightning Chess application, yet it was needed in several places. Following components expect these events:
- General Game Component: ‘New chessboard event’
- Chessboard Component: ‘New board move event’
- Player List Component: ‘New/Update for a player login’
- Challenge List Component: ‘New challenge event’
So that’s four places to include the Streaming API. Needless to say that we won’t make the connection to the streaming API in every single component. That would be a very wrong approach leading to lots of duplicate code. Instead all the logic for subscribing to a certain channel is grouped into one component, making it one additional part of our toolbox.
So how does the encapsulation of components increase the reusability of components?
Simple, we make sure that all the internals of a component are kept internal to that component. We only provide a public interface to the consumer. That consumer has some level of control over the component he is using but only that much defined by the consumed component. Let’s explain this with the example of the Streaming API Component.
Here the public interface is very simple. The component accepts a list of channels to subscribe to. As of that point everything, from subscribing to receiving events, happens within the Streaming API component and is easily reused by other consumers. Consumers are informed through events. These events are Lightning events containing the information provided by the Streaming API.
How do you decide what should be a component and what shouldn’t? It’s a question I heard a few times before and the answer is not that straightforward. My advice is to think before you act and evaluate case by case. Overthink what you are about to develop, try to identify functionality or responsibility, look at what you can reuse and most of all don’t overcomplicate things.
The right solution design or solution architecture are in fact key for success. One cannot build a tall skyscraper by simply stacking rocks together so think before writing even a single line of code.
That looks nice, can I have it?
In the previous section we have seen how we can use encapsulation of components to create flexible and reusable parts of the UI. In this section we’ll have a look at how we can share functionality across components.
I have a dog and my dog is an animal. Sounds familiar? It’s probably one of the most common examples to explain inheritance. I was happy to see that Lightning supports component inheritance. It allows us to create components that are the same at the core but still different. Using component inheritance we take that what is the same and extend it with that what is specific to the component.
Simply put you take that what is the same, you put it in a super component and you extend it the way you want. It provides us with more ways to write flexible and reusable code.Let’s take an example to clarify how Lightning Chess uses inheritance by looking at the Chessboard Component. In fact I have to start by admitting I left out one component in the component summary and high level schema shown above . There is an additional component called Turn Based Game Component. You see where I’m going with this?
If we look at the Chessboard Component we could say that it’s a turn based game much like a dog is an animal. Now that we have the definition ready let’s talk functionality. One key aspect of this turn based game is that there are two players and at all times there is only one actually making a play. What does it mean in terms of the Turn Based Game component? The main function of this component is to store the player information and display whose turn it is. If we take a look at the image below you can see what part of the UI is actually managed by the Turn Based Game Component.
Because the Chessboard Component is inheriting the Turn Based Game Component it automatically receives that part of the UI. In fact the Chessboard doesn’t actually know about that part. The Chessboard is responsible for updating who is the current player, the moment this has to happen can vary between different types of games. What happens in the UI at that point is encapsulated within the Turn Based Game Component.
Remember the checkers game that might be added later on? Since that is also a turn based game that component will simply inherit the Turn Based Game Component and receive this exact same functionality. No need to implement that twice!
Communication is the key to success!
So far we’ve seen how to split up our application into smaller components, where each component functions on its own without interference from the outside. What if I told you that’s not enough? In a way you are still building a whole entity. In most cases you need some form of communication between different components. Let’s take an example of the human body, for once no legos.
Say someone throws a ball at you and you want to catch it. In order to achieve this you need multiple parts of your body. It all starts with your eyes, they are able to see the ball coming towards you. In order to catch the ball you will need your arm and eventually your hand to grip the ball, given that the guy throwing is pretty accurate and you don’t have to make a few steps. Each part has its own function yet we won’t be able to catch that ball when there is no communication between the different parts.
Lightning components are very similar. Each component functions on its own but can’t do much without communication Within Lightning this communication happens through eventing. There are two types of events:
- Application Event: This can be seen as an application wide broadcast. It is not bound to a component but directly to the application. Every component in the application can receive these types of events.
- Component Event: As the name already suggests this event is directly linked to a component and not an application. Component events are typically used to inform a consumer about something directly.
In most cases the component event will be the most applicable since you have more control over the receivers. Be careful when using application events as everyone is listening, you wouldn’t send a private conversation over a public accessible channel either.
Let’s have a look at what this means in terms of Lightning Chess.
Take following example:
- The user clicks one of his pieces
- This will activate the move prediction
- Each reachable location will be highlighted in green
To achieve this we need communication between two different types of components: the Chessboard Component and the Chessboard Location Component. The chessboard contains 64 chessboard locations. When a location is clicked, the location will generate a Component Event to inform the chessboard what location was clicked. The Chessboard Component will then calculate what has to happen based on the event it receives. Remember it’s the Chessboard that knows the full board and knows the chess logic. The Chessboard Location is only there to display the correct state of his location, it only knows itself. Therefor it passes information about the click to his consumer, in this case the Chessboard.
Once the Chessboard has calculated the necessary it will generate an application event and broadcast this to all components in the application. The event contains information on what has to happen. For example it can tell what coordinates (locations) should be set as targetable or if there was a new board move and what piece has moved to which location. Each Chessboard Location is listening to these events and will respond to them with the correct action.
Notice here how we encapsulate responsibility within the Chessboard Location and the Chessboard and still we are able to make them work together in a loosely coupled fashion.
Why make this split? Why not handle everything within the Chessboard component, it looks easier. It might look easier to do all this in one single component but as I’ve said before sometimes you have to think ahead and evaluate your situation. Let me explain you the added value of this event driven approach with two additional examples.
Open for extension
Currently our Lightning Chess application still looks very limited in terms of functionality. So let’s plan to add some. Wouldn’t it be nice to have an overview of each piece that has been beaten so far. Well that’s actually really easy to achieve. We know that our Chessboard is generating application events to inform Chessboard Locations about board moves. We can now easily create another component that listens to the same type of events and based on the information add a chess piece to the overview of fallen pieces.
The only thing we have to do is add this new component to our Chessboard Component, that’s it. We don’t have to change anything, we only extend.
So you’ve been playing a lot of Lightning Chess lately but you can’t seem to beat that one guy that’s much stronger at chess than you. What if we add a new component that would allow you to go over all our previous games and view them step by step?
I say with the above approach this should be fairly easy to achieve. We already have our Chessboard Locations. Remember they are responsible to display the correct state of their own location and this based on the events they receive. We can simply build a component that obtains all the moves for a certain chess game and then feeds them to his own locations through the same events used by the Chessboard. We don’t need our Chessboard here because in essence it’s completely different than the component we are trying to create. Yet because we have split up the Chessboard and the Chessboard Locations into two separate components we can reuse one of them. Again notice the loose coupling, my Chessboard Location does not care who is consuming it. Whether it be the Chessboard or Chess History Component it will still do what it’s supposed to do.
I hope to have shown you the true power of the Lightning Component Framework and how easy it is to actually extend what you have build. Of course with the condition that you structure your components in the correct fashion.
I don’t need you right now…
Alright, last section, it seems I have been writing for ages at this point.
Let’s put some speed in Lightning now. Most of you know what Visualforce is all about and how much of your view logic is located in an Apex controller. Every single UI action results in a callback to server which then returns a new view state. Popular approach in ancient times. Today we are 2016 and this approach can no longer compete with frameworks such as Angular.
Now the server is only called when needed and no longer on every single UI action. The main benefit of this approach is that everything works faster than ever. No more unnecessary server round trips and no huge viewstate going back and forth. Instead we put more logic in our Lightning components.
As always let’s take an example in Lightning Chess.
Same scenario as before:
- The user clicks one of his pieces
- This will activate the move prediction
- Each reachable location will be highlighted in green
All this happens client side. It’s a combination of calculations within the Chessboard and Chessboard Location Components, yet all the calculations stay client side. The server is never called which results in a pretty much instant update of the viewstate.
Putting it all together
My take on the Lightning Component Framework? I love it!
So far I haven’t found anything I wasn’t able to create with Lightning Components and I have been developing full time in Lightning for the past few months.Of course it is still in its early phases but I am certain that Lightning will mature in a short period of time.
The future is now and so is Lightning. If you haven’t played around with Lightning I can only advise you to do so, I guarantee you’ll like it!