7

GraphQL vs React Server Components — Do We Need Both?

 3 years ago
source link: https://blog.bitsrc.io/graphql-vs-react-server-components-do-we-need-both-226c8b1c2cf7
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

GraphQL vs React Server Components — Do We Need Both?

This new type of component promises to revolutionize the way we interact with the back-end.

Image for post
Image for post
Image by Free-Photos from Pixabay

On December 21st of 2020, the React team released the results of in-house research they’ve been doing for a while: a way to run React components on the server. What?! — you say — that’s a travesty! React is a front-end framework — I hear you, but trust me on this one, these peeps had a great idea, and they’re still working on making it even better.

The concept of Server Components is new to the React ecosystem, and it’s still in the early stages, so while it is true that you can already download and play around with the code, remember: a whole lot of things can change between now and production-ready version, so don’t go crazy changing everything you’ve ever written into a server-side component — I don’t care how tempted you might be, stop!

If you haven’t yet, I recommend you go check out their tech talk where they introduce the concept and the demo project (it’s a 1-hour video, but totally worth it) and clone their repo.

But before you go do that! Keep on reading, because I want to give you a quick intro to this concept and why would you need it.

If you’re wondering how React’s new component types fit into future design systems, especially with trending component sharing tools like Bit, I recommend you read this post by Alicia Jones:

What triggered their creation?

Before moving forward, I want to quickly address this — mainly because it explains the title of this article.

Up until now, if you wanted a reliable and performant way of fetching fragmented data (i.e data that was meant for different components but that holds some internal consistency put together) you would, normally, rely on GraphQL for the task.

GraphQL and Relay were the weapons of choice described by Dan Abramov in the video, and it makes sense. Relay’s QueryRenderer helps you define everything you need, following the concepts you’d find inside a React App. However, they wanted more, they wanted a way to do the same thing, but cleaner.

I mean no disrespect to the team behind Relay, their solution has been great so far, and it’s proven an amazing one at that. However, it is also true that it adds quite a lot of code into a front-end codebase, to abstract the developer from the back-end concepts involved. And that translates into harder-to-maintain code.

This was, in turn, one of the motivations behind the creation of Server Components — simplifying the interaction with the back-end by providing native support for it (sort of speak).

Instead of now having to add extra tooling to work with concepts such as database queries, you can now have a seamless experience going from front-end specific code into back-end land and vice versa.

What Are Server Components?

That’s probably the question you’re asking yourself if you’ve not yet watched the video.

Server components are React components that are rendered in the back-end. That’s it, actually, that’s almost it. You see, I’m not saying that the React team suddenly decided to implement SSR into their components. They went one step further and implemented a communication protocol between server and client-side components that made the transition between them invisible.

What is that supposed to mean? Let me show you.

Fragment from the official Demo’s Note.server.js file

This fragment of the note.server.js file from the demo, shows several things:

  1. This component is not using anything front-end or back-end specific other than using HTML and referring to other components.
  2. It’s using the fetch API to pull data from an external service.
  3. And is rendering the results.

Based on these observations, would you say this is a client or a server component? There is no easy way to answer that one, is there? Truth is, this is a server component, but for a very simple reason: it’s pulling data from the server itself (through the fetch call). So why would you put that call in the client, when you can do it directly from the server?

That is one of the main reasons why we’re getting this new type of component: improved performance on IO calls.

Have you also noticed this particular detail? We’re importing several components, some of them have a .client extension and there is one that doesn’t.

Server components and client components can be used together. This to me, is a game-changer. It blurs the wall between front and back like nothing I’ve seen before in JavaScript land.

Server components are, however, a bit restricted, which make total sense, they can’t:

  • Have an interactive code. We can’t define onClick events for example, but then again, that’s what client components are for.
  • Use state or hooks that depend on them.
  • Use effects (so useEffectis not supported)

What Do We Know About Server and Client Components?

So far, what we can tell from the information available online is that:

  • Server components are declared with a .server.js extension and client components are defined with a .client.js extension.
  • Components with nothing more than a .js extensions are shared, which means they can be executed both on the front and on the back. You can think of them as the intersection of server-side and client-side. This means they have all the restrictions of both sides, but can be used interchangeably.
  • Server components will only be executed on the back-end.
  • Server components and their dependencies will never be downloaded to the client. This is major, since it reduces the amount of information the client needs to start executing the app and removes some soft size limitations we had when it came to picking the right dependencies. In other words, we can now add bigger dependencies to server components without the extra latency penalty for the client.
Image for post
Image for post
No .server.js files in that list
  • Shared and client components are loaded on demand. This means your components will not be downloaded by the client until they’re actually needed.
  • Server components don’t render to HTML. In fact the React team developed a custom communication protocol, which allows components to communicate faster.
  • The props sent between client and server components need to values that are serializable into JSON format. This is an understandable restriction since they need a network call, even if you don’t see it in your code. This leaves out callback functions, but pretty much anything else is valid.
  • There is a need for Webpack here. Right now this is only working thanks to a custom Webpack plugin that was developed by the team and is still in alpha version. They also mentioned the possibility of adding support for other bundlers, but right now, Webpack is the chosen one and it will be the first with full support for this feature.

But most importantly: Server components are not meant to replace the use of GraphQL as a way to simplify data gathering (the whole fragment-component thing), but instead, they’re meant to simplify data gathering so that you can use GraphQL or any other solution with the same benefits.

Why Would You Want to Use Server Components?

Server components are a fantastic new tool, still under development, but that already shows a lot of potential benefits.

Let’s quickly go over — what I think — are the main reasons why you’d want to use server components on your future projects:

They simplify communication between front-end and back-end code.

This is true to the point where you no longer need to think about that communication. All you have to do is consider how components are connected.

This is achieved by leveraging the Context component. They’ve added a location object inside the context, which all client components are subscribed to (this seems to be done automatically by one of their unstable functions).

When the location changes based on a user action, the following code is triggered:

Full code can be seen here

They allow you to break the client-server waterfall

One of the major motivations for creating these components was the use case when you have nested components, all fetching information from the back-end.

In this scenario, only once the parent component receives the data, are the children capable of starting their request. And the same happens if these children have children of their own. This effectively creates a waterfall that is heavily penalized by the potential latency between client and server.

By using server components, we limit that latency to the time the server requires to access the external data source. We still have the same roundtrip there, but at a lower cost.

They provide a more cohesive and easier to maintain codebase with a smaller bundle size

This point is major for big applications. Right now, the bundle size is a potential problem for the user if they are behind a slow internet connection. However, depending on your use case, that size can be highly reduced if you were to move all data-fetching operations to the back-end, including their dependencies.

As I’ve already mentioned, server components are never downloaded to the client, and the same goes for their dependencies. This means the final bundle size is considerably smaller. This is also achieved by simplifying the code abstractions used, and logically grouping data-fetching code (server components) on one side, and user-interacting code (client components) on another one.

They provide full access to Node.js back-end API

For back-end related code, this is a major win. You automatically gain the ability to use libraries such as Sequelize, Mongoose and other ORMs (to give you an example) directly in your React code.

You can also use Node’s IO API directly, and to help you with this, the React team is also building ReactIO, a thin wrapper around Node’s I/O API to help you even further.

This in turn, could simplify the task of pulling content from static sources, simply by using fs.readFile like you would, but sending the content directly into a React component. A win-win in my book.

Is It Ready For Production?

Heck no, this is their early release and they’re just trying to get the community’s feedback, trying to understand if they would like it or not.

You can definitely play around with their demo, share your opinion about it, but stay away from using this code in production. In fact, you’ll notice that most of their added API is prefixed with unstable for a reason. This API will likely change in the future once they start getting feedback, and there is no telling when server components will be production-ready at this point, so hold your horses, and just limit yourself to play around and do some tests.

According to their presentation, they’re still missing some key aspects of their initial design, such as:

  • A bigger and more robust API
  • Finishing concurrent mode to optimize the way they get the content from the backend.
  • Production ready bundler plugin. As I mentioned before, right now it looks like Webpack will be the first one here, but I’m guessing the idea is to keep growing in support.
  • Ecosystem conventions, like everything, need to be revisited and created where necessary.
  • Streaming HTML renderer
  • Framework and router integration, since right now they’ve mostly hacked a quick solution using the context object.

There is still plenty to be added, but as a PoC of the technology, this version is already very promising.

If you ask me, ever since Node.js was released, we’ve been hearing about the amazing benefit that was having JavaScript for both, back-end and front-end environments. But in my humble opinion, this is the first time I see that concept being put into practice.

Server components breach the front-back gap to a point where moving from one place to the other requires very little effort. They’re still far from ready, and things will probably change before you can use them in production, but as of now, they’re ready for you to test and see where this new technology might go.

Will you be using server components? Or do you rather stay with the known and trusty way you’re using right now?

Learn More


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK