Killing BFFs with GraphQL and Next.js


Frontend applications are getting more and more complicated, often delivering far more than just a UI. With this growing complexity comes a growing need for knowledge from the developers creating it, as they have to deal with matters like state-management, authorization, routing and more. In this talk, I'll show you how to use GraphQL in your Next.js application to create a data layer for your application, that exists between your frontend and your backend. In this data layer, you can handle complex matters to help you to keep your frontend application clean and "stupid".



Hello everyone, and welcome to my talk: Killing BFFs with Next.js. So I guess it's almost Halloween, so that's a great way to start out with some Halloween opening. So Killing BFFs with Next.js is not a Halloween talk, but is something that is probably interesting for most of you.

So what is this talk about? So let's start out about, you probably already know about microservices or maybe you're still using a monolith. You also have BFFs in monoliths, but those are a bit different. So I imagine you have microservices and then you have a backend for frontend for your web client. You may be able to separate backend for frontend for your mobile client. So this is probably perfectly fine, but it is something that takes a lot of extra work for your team and maybe also for your backend developers, because they need to make sure the microservices are tailored to do different backend for frontends. So that's something we are discussing today in this talk. So I hope you all enjoy it and if you have any questions afterwards, there is some time for Q and A.

[01:20] So backend for frontends could also be this, when you and your backend for frontend know something nobody else does. So this is actually a problem because your mobile client may be doing something with your mobile backend for frontend while the web client wants to do the same thing, but maybe the logic isn't implemented there. So backend for frontends aren't only a way to make things easier for the client, it can also lead to extra complication because maybe one client knows something that another client doesn't.

So a little bit about myself. So my name is Roy, you can find me on Twitter with my handle @gethackteam, and I'm an entrepreneur software engineer, but I also write some books and am a regular speaker at conferences. So if you don't know me already, please find me on Twitter. Currently also work with a company called StepZen and what they're doing, they're making one unified GraphQL API for all your data sources. So that's pretty cool if you want to get started with GraphQL. And also I give workshops and trainings through my own company, Hackteam. So make sure to go to the website as well if you have questions about that, but also make sure to just enjoy this talk and try to learn something new.

How did we get to BFFs?

[02:27] So how do we go to backend for frontends? So backend for frontends or BFFs, as I already said, how do we actually go there?

So I think the first time most of you got in touch with API for the first time was monoliths. So monoliths are, as they say, one API to rule them all. And monoliths can be RiskAPIs, they can also be GraphQL APIs, maybe even SOAP if you've started web development or development in general a long time ago. So monoliths are basically one API to rule them all. And if you're working with different clients from one monolith, and typically you would've separate RISK endpoints, or if you're using GraphQL which can be a great way to have different clients for one monolith, you probably have different queries that are tailored to different clients that are consuming your GraphQL or REST API. So it's basically monolith's one API to rule them all, which is perfectly fine because most companies don't even get to a size that they need to have microservices.

But if you get there, then microservices is also something that's very interesting for API developers, but for frontend developers or React developers, it will lead to some extra difficulties because I always like this meme about microservices. So when your boss tells you we're converting to microservices, this is what actually can happen.

[03:45] So microservices are tiny services, that's why micro, and it's one service for a separate goal. So maybe you have one service for your authentication, you have one service to get your users, one service to get maybe information about products, another service to get for your checkout orders. All these things will be divided into different microservices. And these microservices of course need to be unified somewhere, maybe an API gateway, maybe your frontend is calling older microservices separately, which is something you should try to avoid. So even if you're not using backend for frontends, it can be an interesting outcome for this talk, learn about how you can use Next.js in order to have one unified gateway for all your microservices.

What are BFFs good for?

[04:31] So what our backend for frontends is good for, so we now sort of know why we have backend for frontend. So we have monolith APIs, which is nice, but can be confusing if you have multiple clients using the same monolith. We already also saw microservices which are also perfectly fine, but it can also be very confusing if you don't have an API gateway in place or the vision about who's responsible for what microservices very, very strange. Could also be depending on your company. So what is backend for frontends good for?

So I already saw this picture. So you could have set of microservices, or it could also be a monolith. That's something you also see happening. So people have a backend for frontends that's connected to the monoliths and from the monolith, they just have separate REST APIs that they're using and APIs that they aren't using, but it's backend for frontends or backend for mobile ends. How I like to call them, just call mobile client and backend for frontends as well. So we have a backend for frontends for our web client. We have one for mobile client. And the reason that these backend for frontends are there is probably because you have very different experiences.

[05:38] So maybe you have a web client that is a huge dashboard interface while your mobile client is just a very simple version of that. So for that use case, backend for frontends are great because you actually can separate concerns. You can make sure you don't have any interactions between different clients. And also if one thing breaks, the other thing doesn't necessarily also breaks. Unless of course, one of your underlying microservices or monolith breaks.

So a very different experience is one way to have a one reason to have a backend for frontends. And also, like I said, a separation of concerns. So maybe you're doing very different things in your mobile clients and you don't want to have your web client be aware of these changes. So then the separation of concerns for this is perfect because maybe you also have more separations of concerns with even your services. So maybe your microservices or part of your monoliths are specifically tailored to mobile, then it can be a good use case to have this backend for frontend better.

[06:35] And then the one I like the most is actually autonomy. So if you have a large scale company or maybe even a smaller company with one guy or girl doing the web client, another person doing the mobile clients, and then one person doing backends, for this autonomy already works because the backend people don't have to worry about how the frontend consumes the product while the web person can make one BFF for their web clients that's specifically used by the web clients and he or she's the only person to actually use this. And the same goes for the mobile. So maybe if one person is doing mobile, they can build their own BFF, they don't have to worry about breaking anything in a web client. So autonomy is a really good reason to start using backend for frontends.


[07:18] But more services also have a downside, of course, and this is something I want to talk about today. So having more services always has a downside because if we go back to this example, so you have the autonomy part, but you have the services that need to be deployed, you have a backend for frontends that needs to be deployed and you have a web client that needs to be deployed. So if you're working on a web client, you have three things that are important for you that need to be deployed in order to have your service working. So this is something to worry about because you have 1, 2, 3 services and then the mobile person also has three services. And then there are already people working together, maybe on their microservices on the back, because maybe the web person is already helping out to the backend person. Then the other thing goes around and it's for just a startup.

So if you're a big company, you maybe have multiple teams working on a web client, multiple teams working with the backend for frontend and multiple teams working on your microservices. So this is something to worry about because extra services also mean extra work. So this downside is for maintaining, for deploying, but also for innovation right? Because we want to make changes somewhere. You need to talk with this whole chain of people in order to make sure you can actually make the changes you want to make.

Downside Next.js API Routes

[08:30] So Next.js API Routes make this actually very simple. So I think they started this not so long ago. So with API Routes, you can actually create, in other words actually say it, you can create API Routes from Next.js. So Next.js is the internal routing system based on their files. So maybe you have pages/welcome. Then you would have actually a /welcome page on your website, which people can go to in order to see a welcome message. For the API, it's the same, you can just have pages/API/welcome. And then you have an API to get maybe a block of JSON that you want to display on the welcome API page. So Next.js API Routes, they make this very simple. And before we actually go under the hood why API Routes are good let's show what it will do to our architecture.

So before, we had one backend for frontend for the web that was used by our web client, and then we had a separate one for the mobile and then a mobile client using it and of course all the services, but now actually for the frontend developers or the web developers, it already becomes much easier because now they have just one single BFF that's built inside the Next.js app that they can do all the things for. So they don't have to worry about deployment, they don't have to worry about DNS, they don't have to worry about maybe where things live within a Kubernetes infrastructure. So it makes things for web client way easier, but also the mobile BFF of course, could be able to use this BFF as well. So maybe if you don't have a separate BFF for web or mobile, it can be a nice solution.

[10:05] But maybe even like I said before, if you're now calling all your microservices directly from your web clients without a BFF, the BFF can still be there in place in order to help you to do this more efficiently because then always you have a very nice way of seeing where things pull together. You have one way to actually normalize to clean your data. So Next.js is very good with this, especially with API Routes in order to build a BFF for your web app.

And of course there will be still the separations of concerns because if you are planning to have multiple BFFs or multiple backends for frontends, then you still have separation of concerns. Because the web people are responsible for what happens in the web BFF and the mobile people don't have to worry about it. As long as they're not building their mobile application with Next.js of course, which is indeed possible with React Native, but it's a whole different discussion.

[10:55] And we also have autonomy still, so we still have autonomy there because the web people still are responsible for what's going on in Next.js app. They're responsible for what's going on there in terms of data normalization, data cleaning in terms of what APIs will be called. So everything will be done from just one single Next step, making it somewhat of a framework that's more full stack than we saw before. So full stack frameworks are becoming more popular in a React ecosystem. So like a Remix or Blitz.js, maybe even Redwood for Node.js. So things are becoming more and more autonomous in terms of full stack considerations for React devs. And Next.js is also following this with the API Routes.

And most of all, what I see is the most important thing is you don't have the additional overhead of deployments of making sure things are out there or making sure things are up, having DNS, being responsible for other services, need to apply to changes in other services, need to align maybe what's going on, there's deployment at your web client, your mobile client and all the other BFFs out there. So additional overhead really is gone when you start using API routes. And there are way more benefits, which I will show you in a bit. But most of all, for me having all your deployments and all your development going on in one single directory or maybe one single repository is a huge accomplishment. So it will make Next.js way more approachable for people that are doing things full stack and maybe now have something running with express.


[12:25] So let's check it out. So let's see what this looks like. So let me switch to my code here. So there are multiple ways to use this pattern with the API Routes. And before we actually go into backend for frontends, let's go to something like this, or it's actually somewhat a backend for frontends. So I've made an implementation with SendGrid, it's a way to send emails around. And what I did over here, actually one problem I have, I was using SendGrid directly from my client. And one downside you have, if you start interacting with third party APIs from your client, or maybe on microservices from the client, you can actually leak information. So if you look here, I have an API key, I have a list ID and now I'm sending this from a backend API Route. It will be handled in the backend. So the user won't see that there is a network request going on to SendGrid. The user will only see there is a network request going to API/signup-newsletter. So this is a great way to actually also hide in the underlying information about maybe your credentials, about your microservice architecture, about what service is responsible for what.

So we're doing it like this, it's one of the examples of having a BFF is being able to hide underlying architectural patterns or credentials to a user. So if I would be doing this from the client, my user could actually see I'm making a request to SendGrid. So I'm already giving away which third party I'm using for emails. Then I'm also giving away my SendGrid API key and even my list ID. So I've doing this from a client, it wouldn't be that smart, not really to say stupid, but let's say it's not really smart because you're leaking all this information to a user and a user would be able to see this.

[14:10] But what you also don't want to do, if you're just building a frontend, you don't want to build an entire API in order to do it. So previously I either had to ask my backend developer, "Hey, can you make an API call in which I can send something to a third party API?" And that probably will work out, but I need to be reliant on a different team. If I already have my backend for frontend, I can probably make the change there or maybe can ask a backend developer there to change but I'm still reliant on a different service. So with API routes, I can do all these things just from one single code base. So you would create a page /API/signup-newsletter. And this way you can actually hide all the things that are going on here for my user. So you're not giving away your third party API, you're not giving away your microservice architecture or pattern. And also, which is the most important one, you're not leaking any sensitive data, because that's something you don't want to do. I'm going to assume most of our users are quite friendly, but maybe if you find an actual hacker on your website, then it's something you specifically don't want to do.

So another cool use case, which I also write down here. You can even use with GraphQL. So this is one of the biggest upsides I see here, using this together with GraphQL. And this is a really cool use case specifically because GraphQL makes things way simpler for most of us because we can have one API route that is a GraphQL API route because GraphQL is a single API. And from there we can do all our backend for frontends things or cleaning, all the data normalization, make sure all patterns are there. So it really helps us making things more straightforward.

[15:54] So let's go back to the code and see what it looks like. So we have a GraphQL endpoint. So we just create an endpoint pages /API/GraphQL in here, define a schema. You define your resolvers and your resolvers will probably be just API calls to somewhere. So this will probably be return call Microservice X. So you know the drill, you're probably creating resolvers. You're saying which microservices you need to call. And then you actually create your schema. You're actually going to create an executable schema.

And before I go to this, let's go here. So what I'm doing here, I'm creating an executable schema, but what I'm also doing, I'm running middleware, which is actually a really nice future because the way they created API Routes to make sure they are compatible with middleware to connect different services so like we actually know from Express. So I can now use Express GraphQL and basically every other middleware for Express from my API route. So there's no actual need to spin up an Express server. You can actually do all these things directly from one API route in Next.js. So it's going to save a huge amount of time of the deployment of making sure there's a Docker, making sure there are all these other things and not saying even where to host them. Because of the API routes, you can also run them serverless, which is a really nice way of doing this because by having it serverless, you don't have to worry about these things like deployment being available, being up and of course Next.js being , it's also a support for that.

[15:54] And there are also cool new tools if you want to make sure that your serverless apps and APIs are actually running, but those maybe we can save them for the Q and A. So it is running middleware is a really cool thing because by having this executable way of extending your API routes, it also makes it really future proof because of all the things that have already been built, all the open-source libraries for different express APIs, you can already do them now from API routes. So using this, I can just basically create a GraphQL API that runs on an API route, has all my resolvers, has my schema there. Run in the middleware like Express GraphQLl, but maybe other middleware for authentication, middleware for logging all just from one directory. So it's a really cool, cool feature to have.

Learn more

[18:28] So yeah. So if you want to learn more about using API routes in Next.js, of course I need you to check out the documentation because the documentation really helps you try and understand API routes. But besides that, I'm also launching a course about using Next.js with GraphQL in API routes. So if you are interested in this course, make sure to go to my website. So and you could found link to the Building the Serverless GraphQL API in Next.js. In this course, I will show of course more in depth the code we already saw before and also learn some cool new tricks about API routes, Next.js most of all also GraphQL. So we'll be building cool things like network pulling on the backend, but also how to handle these API routes in Next.js, and most of all also learn how to deploy them serverless.

So if you do want to learn more about Next.js, make sure to go to Next.js websites to know more about my courses. Please go to my website. Most of all, if you want to learn more about React, GraphQL type scripts, these kinds of things, make sure to follow me on Twitter or find my videos on YouTube. And then I wish you really enjoyed the conference so far. You will still enjoy the conference talks coming up because if I look at the schedule, I see there's some really nice people talking about really cool things so make sure to stick around. And then I hope to see your questions flowing in on Twitter or maybe some other way you can find me. Thank you, everyone.

21 min
25 Oct, 2021

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Workshops on related topic