One of the most powerful concepts introduced by Angular 2 is the move to a Component based architecture.
Components are pieces of UI and logic bound together into reusable and self contained units.
There are two important benefits about Components:
We can reuse Components throughout our apps
When something changes in the inner logic and UI of a Component, it shouldn’t affect the other Components outside of it
Those are great benefits, but are they still valid when we start interacting with the server?
I’ll argue in this article that the current way of calling the server with REST API through central Angular services is not a good fit and that co-locating queries with view logic is the natural extension to the component based architecture.
Calling the server with REST API through central services
Currently in Angular apps, in order to fetch data from the server, we usually import a service that handle the fetching logic for us:
var app = angular.module('myApp', ['ngResource']);
When we moved to Component based architecture, we switched the Controller to the Component class, but in most examples out there, the way we fetch data hasn’t really changed.
...
import { Headers, Http } from '@angular/http';
import 'rxjs/add/operator/toPromise';
import { Friend } from ‘./friend’;
@Injectable()
export class FriendService {
constructor(private http: Http) { }
And that introduces an issue — What happens if now we need to get different data from the server?
Let’s look at an example of the issue, we’ll use this Component tree as an example:
and let’s say the we call a service on the parent `FriendsList` Component that fetches all the data for the Component tree.
Now let’s ask two simple questions:
What happens when we need to change Component to display new fields?
How do we reuse Component in a different place in our app and still fetch the data it needs?
For the first question, we will need to change the server endpoint to either:
Change the existing one to fetch the new data (might change other Components who use the same endpoint and service)
or
Add a new endpoint with the new data structure we want and change the service to support the new endpoint
In either of those solutions — Our Components are no longer self contained
As for the second question, we would need to create or change the service to support the new Component tree that in under, making it not reusable!
Needed solution
So what do we need that is missing with current solutions:
Each Component could specify its own data dependencies without knowing a central service or another parent Component in the current render tree
When we render a tree of Components, we will fetch exactly the information that this Component tree needs which is a combination of the requirements of each Component
We would do that in one single request
We need an API layer that will bring us new fields without changing existing and exposing new endpoint
Solution — GraphQL Client
With GraphQL, we can co-locate the server data requirements for each Component, and then use a GraphQL Client like angular2-apollo to handle the merging of those needs into one single request that gets exactly what we need.
this is of course not a full working app, I’ll add links to full implementation at the end
Now let’s get back to our original questions:
What happens when we need to change Component to display new fields?
How do we reuse Component in a different place in our app and still fetch the data it needs?
The answer now, is that you only need to change \ Component itself and that’s it:
const FriendInfoQuery = gql`
query getFriendInfo($id: Int!) {
Friend(id: $id) {
id
name
mutual_friends {
count
}
age
}
}
`;
...
template: `
<div>
<p>{{friend.name}}</p>
<p>{{friend.mutual_friends.count}} mutual friends</p>
<p>{{friend.age}} years old</p>
</div>
`
})
export class FriendInfoComponent {
...
}
That’s it!
We don’t need to change any of its parent Components
We don’t need to change the API endpoint
We can move it around and reuse it in any Component tree
It is now a true reusable, self contained Component.
Summary
In this article I’ve tried to make the point that we should adjust our way of fetching data from the server to the new paradigms Angular 2.0 introduced.
It’s Important to note that those concepts and solutions are also true and valid in an Angular 1.x app that is Component based (and Apollo Client work with it as well).
Also, an important point is that you can use this solution alongside your regular REST services and not instead of them, add it where it fits and make sense to you.
There are many more benefits for this type of architecture and more details about how we manage those queries and app state which I’ll touch on later posts
Here are few notable talks and resources about those techniques, some are for React but the concepts are still the same:
To learn more about how Angular works with GraphQL, hear directly from Angular core team member Jeff Cross at the upcoming GraphQL Summit in San Francisco on October 26th!
One of the most powerful concepts introduced by Angular 2 is the move to a Component based architecture.
Components are pieces of UI and logic bound together into reusable and self contained units.
There are two important benefits about Components:
We can reuse Components throughout our apps
When something changes in the inner logic and UI of a Component, it shouldn’t affect the other Components outside of it
Those are great benefits, but are they still valid when we start interacting with the server?
I’ll argue in this article that the current way of calling the server with REST API through central Angular services is not a good fit and that co-locating queries with view logic is the natural extension to the component based architecture.
Calling the server with REST API through central services
Currently in Angular apps, in order to fetch data from the server, we usually import a service that handle the fetching logic for us:
When we moved to Component based architecture, we switched the Controller to the Component class, but in most examples out there, the way we fetch data hasn’t really changed.
And that introduces an issue — What happens if now we need to get different data from the server?
Let’s look at an example of the issue, we’ll use this Component tree as an example:
and let’s say the we call a service on the parent `FriendsList` Component that fetches all the data for the Component tree.
Now let’s ask two simple questions:
What happens when we need to change Component to display new fields?
How do we reuse Component in a different place in our app and still fetch the data it needs?
For the first question, we will need to change the server endpoint to either:
or
In either of those solutions — Our Components are no longer self contained
As for the second question, we would need to create or change the service to support the new Component tree that in under, making it not reusable!
Needed solution
So what do we need that is missing with current solutions:
Each Component could specify its own data dependencies without knowing a central service or another parent Component in the current render tree
When we render a tree of Components, we will fetch exactly the information that this Component tree needs which is a combination of the requirements of each Component
We would do that in one single request
We need an API layer that will bring us new fields without changing existing and exposing new endpoint
Solution — GraphQL Client
With GraphQL, we can co-locate the server data requirements for each Component, and then use a GraphQL Client like angular2-apollo to handle the merging of those needs into one single request that gets exactly what we need.
Let’s have a look:
Now let’s get back to our original questions:
What happens when we need to change Component to display new fields?
How do we reuse Component in a different place in our app and still fetch the data it needs?
The answer now, is that you only need to change \ Component itself and that’s it:
That’s it!
It is now a true reusable, self contained Component.
Summary
In this article I’ve tried to make the point that we should adjust our way of fetching data from the server to the new paradigms Angular 2.0 introduced.
It’s Important to note that those concepts and solutions are also true and valid in an Angular 1.x app that is Component based (and Apollo Client work with it as well).
Also, an important point is that you can use this solution alongside your regular REST services and not instead of them, add it where it fits and make sense to you.
Here are few notable talks and resources about those techniques, some are for React but the concepts are still the same:
Data fetching for React applications at Facebook
Modernize your Angular apps with GraphQL
Angular2-Githunt example
To learn more about how Angular works with GraphQL, hear directly from Angular core team member Jeff Cross at the upcoming GraphQL Summit in San Francisco on October 26th!