Overview

About this video

What You'll Learn

  1. Create standalone GraphQL graphs in TypeScript with resolvers and deploy them to Grafbase Cloud.
  2. Extend product types across subgraphs so federated queries can resolve reviews from another service.
  3. Use connectors and edge deployment to unify APIs while keeping responses fast and typed.

Hands-on with Grafbase and founder Fredrik Bjork. We build standalone GraphQL subgraphs with the TypeScript SDK, compose products and reviews into a federated graph, extend types across teams, and deploy via the Grafbase Cloud GitHub integration.

Chapters

Jump to a chapter

  1. 1:48 Introduction
  2. 2:07 What is Grafbase? (Origin Story)
  3. 4:13 GraphQL Challenges & Grafbase Solution
  4. 6:12 Architecture: Rust, WebAssembly, Edge
  5. 10:03 Why Rust? (Team & Tech Choice)
  6. 12:25 Starting the Hands-on Demo & Setup
  7. 14:11 Creating a Standalone Graph (Code-First)
  8. 21:13 Resolvers and Edge Deployment
  9. 24:22 Introduction to Federation and Subgraphs
  10. 33:56 Extending Types Across Subgraphs (Live Demo)
  11. 47:51 Benefits of Federation for Teams
  12. 50:02 Deploying to Grafbase Cloud (GitHub Integration)
  13. 58:41 Additional Features: Caching, Analytics & Dogfooding
  14. 1:00:34 Experimental Feature: Key-Value Store
  15. 1:18:54 Roadmap & Upcoming Features
  16. 1:23:32 Conclusion and Farewell
Transcript

Full transcript

Generated from the English captions. Timestamps jump the player to that moment.

Read the full transcript

1:47 Hello, and welcome back to the Rawkode Academy. I'm your host, David Flanagan, known across the Internet as Rawkode. Today is another episode of Rawkode Live, a show where we get hands on with really cool software just in general within the cloud native space, the Kubernetes space, the front end space, the API space, you name it. And today is no exception. Today, we're taking a look at Grafbase. It is a platform for building GraphQL based APIs. Now to join us today and guide us on our journey is founder and CEO, Frederick. Hello. How are you? Hey.

2:07 What is Grafbase? (Origin Story)

2:21 Thanks for having me. No. My pleasure. It's always a joy for me when there's a product out there, a piece of software that I discover and I'm like, I could use that. And then when we get to do a session on it, I'm always even more pumped. And then to top it, the wee cherry on the cake is this is all powered by some pretty cool Rust code as well. So, again, my pleasure. Thank you for joining me today. Thanks. Yes. My name is Yeah. Please go take a minute. Yeah. Yeah. My name is Frederick. I'm the

2:50 founder of Grafbase. And just one minute summary of Grafbase. It's a fully managed GraphQL platform with a focus on developer experience. So we or I I've been using GraphQL almost since the beginning, since 2015, '20 '16. I was previously the CTO at a company called The RealReal based in San Francisco, and we were building front end experiences as people do, web and native iOS and Android. And we had lots of data silos, and we were using microservices and rest APIs. And we discovered GraphQL as a way to solve some of the challenges that we had,

3:36 you know, in terms of optimizing for a number of requests, only fetching what the the client needs. So we we adopted GraphQL early on, and I've been a fan ever since. When I left The RealReal three years ago, I decided to build a company called Grafbase, which is essentially a developer experience play to build and deploy GraphQL API similar to what Netafy and Rawkode have done for the front end cloud we are doing for the GraphQL cloud. Awesome. Thank you for sharing. Let's touch on a few of those points just because I feel there'll be good context

4:13 GraphQL Challenges & Grafbase Solution

4:19 for the audience. Now you said the GraphQL solves a certain subset or a certain set of challenges, right, that people have with with REST APIs or REST like APIs. I definitely feel the the same. I do not enjoy building CRUD REST style APIs. GraphQL comes with a type system, which I think just solves more problems than we get, but we do get some challenges. Could you maybe go into them in a little bit more details where people struggle with GraphQL and why they may want to look at something like Grafbase and what challenges it solves?

4:54 Definitely. So so, I mean, it's fair to say that starting off building a REST API is easier. You can quickly, on any kind of framework or language, set up a RESTful route. You have a resource. You know? Typically, it starts with users or something like that and go posts, comments, or whatever it is you're building. And it's it's quite intuitive, but, you know, it's not documented most likely. You probably don't have any types or documentation, like I said, and you start building your your front end, application. But it's once you start re you know, querying multiple things, you will make multiple requests

5:36 to your API. So performance suffers as well as, fetching the data that you need to display the page with REST. You know, it varies, but most likely, you would just fetch the whole resource even if you only need a few a subset of the fields of that resource. So the payload is also bigger. And when you start evolving the schema, you've all seen it, you know, v one, v two, v three, it's quite painful to have multiple rest rest endpoints of the same resource, and, GraphQL really solves a lot of that. But to address to address the question,

6:12 Architecture: Rust, WebAssembly, Edge

6:17 you know, building GraphQL APIs is has a steeper learning curve. Right? So I would say Grafbase helps to we we want to help address that, gap essentially where we wanna make it more accessible to any engineer, but in particularly full stack front end devs who might be building a new GraphQL endpoint for their front end application, and they have a bunch of data sources that they need to, you know, they need to fulfill their their their pages or their screens. And we we built a bunch of features for that. Right? So one of them is what we call the

6:56 connectors that you can then point your configuration to, let's say, a GraphQL endpoint or an open API, REST API spec databases like Mongo or Postgres, and we will then do a lot of that crowd work for you. That's quite labor intensive. But but even, like, manually creating resolvers and defining types, we built a an SDK in TypeScript that makes it a bit easier and less daunting, I would say. Yeah. Definitely. I love you know, you said at the start, it's focuses on, like, developer experience. And I think that that really comes through when you start to play with the product.

7:41 And, you know, I have been exploring and playing with this a few times now for my own Academy API, and everything was just really simple. And I like that even though you built all of this in Rust, the TypeScript has the SDK because that's where the developers are usually building these APIs are. Right? You've went to them where you're using I'm assuming, the one who put words in your mouth. But I'm assuming you use TypeScript and you didn't get people a Rust SDK because those are the people that are in this space. These are the people that are building

8:09 these platforms or APIs. Is is that correct, or did I just make that up? No. I mean, it's certainly I would say we have two kind of primary audiences that use Grafbase. One is the front end and mobile developers who typically build what we call back end for front end, which is a new GraphQL endpoint from existing APIs and data sources. They really appreciate the TypeScript SDK that it can live inside the mono repo with cogeneration and all of that stuff in one one place. Right? So it's really great for them. Then there's kind of the platform teams,

8:47 back end teams. There it varies. You know? I think we we still support SDL. Right? That's kind of how we started actually because it is agnostic. Right? But who knows? We we might launch Python and Rust SDKs in the future. Because another thing we haven't talked about is the fact that we we deploy the API itself to to the edge. Right? The edge the global edge network of 300 locations that runs your endpoint in a v eight isolate. So we compile from Rust to WebAssembly to achieve that. Right? So you get if you think about Lambda, which is like a

9:30 serverless function, but it's globally distributed. So without cold starts, you get fifteen, twenty milliseconds response times on a cold boot for your for your for for all your users. Right? So it's really, really powerful if you wanna do authentication, caching, personalization, geo geolocation, that kind of stuff. It can happen right next to user, and then you can go back to the origin depending on what you need to do. So it opens up to this really cool use cases. You're just seeing all the right things. I mean, my favorite three buzzwords are Rust, WebAssembly, and Edge. So, you know, tick tick and

10:03 Why Rust? (Team & Tech Choice)

10:07 and tick. Let's let's touch on the Rust quickly before oh, yeah. I mean, I completely overengineering the Rawkode Academy platform that we're launching. And I just made this I was like, I'm not gonna have a server in AMS 1 or NYC or something like that. So I want I want it to run at the edge. And I just have to know I mentioned ever since. But I I I I'm not gonna answer that just now. What I wanna get into is Rust. Now, Rust is not an easy language language to learn. I've been writing Rust for

10:39 six or seven years now, and I still suck at it. However, I'm curious, did you have any experience with Rust before going in to write in Grafbase, or was this your first project, and what has that learning curve been like if so? Yeah. Great question. I mean, I I started prototyping in TypeScript, like, sort of three plus years ago just to get something up and running quickly. It was, you know, really hacky and probably I don't wanna share too much of the of the first version was built, but but it worked. Right? And then, like, definitely,

11:14 the number one goal was to have something that was performant, scalable, and compiled to WebAssembly easily. Right? So the tooling for that was really important. And, of course, something that was typed, something that developed like, something I can see myself writing for the coming ten plus years. And, you know, this was 2021. So, you know, WebAssembly was really mature and Rust Rust itself was mature and was on the rise, and it's still on the rise. So it made a lot of sense for us to to adopt it. But I've been using it a bit on the side, honestly,

11:54 but my strategy was go out and hire, like, a players in the Rust space. Right? So people who had been building Rust for several years. So we brought on really knowledgeable people on the team, and that's really paid dividends as we as we built Grafbase. Awesome. Love it. And maybe your team are the people I should be heading up, and I get stuck with a lifetime issue then because that seems to happen very regularly. No. Yes. Yeah. Thank you for sharing all of that. It was really interesting. I think now is the time where we actually stop talking about

12:25 Starting the Hands-on Demo & Setup

12:31 how awesome Grafbase is and actually show people some of the things that they could do with that. And I think, you know, as we explore, if there's any of the questions that people have in the audience or something you want to see, just drop them into the comments. We're always happy to to tweak things as required. So let me pull up my screen share where we have the Grafbase website. You can find us at graphbase.com. That is Grafbase, g r a f, base. And now this is completely pointless to today's demo. It's something that I

13:04 loved, and I don't know if it's just something I haven't seen before. But I'm assuming you've right clicked on your logo before. Right? I think, yeah. There's just this neat feature. Oh, come on, computer. No. You're not gonna do it. Oh, there we go. Yeah. Don't know what's going on with my computer. Yeah. Where it allows me to download the icon or the full logo, which is such such a nice touch. Those small little details made me smile. I just thought I would share that, but completely irrelevant to what we're gonna look at. So It's the small things in life.

13:41 It was really weird. And again, not that relevant. But I was exploring using Vivaldi as my browser and I right clicked like, I think Grafbase was the first website I went on to because I was preparing for this. And I right clicked, and then I was like, oh, that's a cool Vivaldi feature. And then it didn't work in any other website, and then I realized, oh, you have actually just built that into your website. And I was like, you know, not only do you have a commitment to the developer experience, but it goes right across the stack. So

14:07 and so from here, what we get back on track and we'll go to the documentation. And as always in Rawkode Live, we haven't really done anything in advance. Although, Frederick was kind enough to provide a few little bits of code to get us started. But we're gonna start from zero and work towards getting this working. And we have a pretty cool couple of things to show in the process. So the getting started guide here will guide you through all the front ends and everything that you need to know to build your first API. You can go to the quick start and

14:11 Creating a Standalone Graph (Code-First)

14:43 this is one of the things that confused me first is that you are you have a Rust engine and CLI, but you're can deliver the binary to people via NPM. Right? That that's what's happening here. And that's not that wasn't something I don't I don't think I'd actually seen that before until I was exploring Grafbase. But I guess, again, it makes sense if you're working or you're developing people that are using your product to come from an a node or TypeScript background. This is a pretty nice way just to deliver that pain away to them. I thought that was a nice

15:19 touch. And it it is a thin wrapper on on top. But but, yeah, NPM is most people have it installed whether you're a no developer or not. And then we are we are gonna publish to Homebrew and crates.i0 as well. We're gonna resume crates.io. It stopped working for a bit, but those will also be available soon. Cool. Alright. So people can create their own Grafbase project with NPS Graphbase then. Now, let's take a look at what we're starting at today. So this well, we start with products. It should be nice and simple. Right? Mhmm. Okay.

16:06 So we have a package dot JSON for a products API, and you put in some of these scripts, which we'll get to momentarily. But in order to really kick things off, this Grafbase is the CLI and this one here is your TypeScript SDK. And we have a Grafbase configuration. So from what I understand from the documentation, this is how you can spec out and build a GraphQL API when you want to start from nothing. This is the kind of your phase one. Is that right? Yeah. This is a I guess we could take a step back

16:44 and talk about what federation is and what a subgraph is, and then, we can dive into how to start composing your schema. Well, this is the standalone graph. Right? So, like, there's no concept of federation or effluent at at the moment. Yeah. I mean, there's a few things sprinkled in here that are relevant to federation. Up top there, you we actually you'd say, hey. This is a subgraph in this time alone arguments. And then we also add, you know, the key to the end of the product there. The key we're saying the field ID is the

17:22 key, and that's a concept in federation. And then we're yeah. Okay. So Well, I'll tell you what. Let's I'm gonna break your example first. Right? Because I always like to know how these things change things. So if I remove that, that doesn't break anything. Correct? Yeah. That's right. And we could just comment off the key. And now we just have a standalone subgraph. Is that is that correct? Yep. Yep. We we we just have a a graph well, we have the potential here to have a GraphQL API. So let's let's get this working so that people can see what Grafbase does,

18:01 and then then we'll come back to the code. Sorry. Sometimes I just like to go off script and see what happens. But we have apps, reviews. We got the reviews. Right? Think it's products. Yeah. I should never trust anything I say. Now, you've already created those package scripts for us. So, if I pop this open, we oh, wrong one. Let's pop the right one. And we should be able to run an NPM install followed by an NPM dev and we get a GraphQL API. So, let's just make sure that works. Let's I don't have PMPM.

18:45 Do it this way. While that runs just in case it's slow, we did get a question. Is there an install section and the documentation for a non NPM install? I don't think there is. And, Frederick, can correct me if I'm wrong, but if you go to GitHub, Grafbase, Grafbase, there is a releases page with binaries. So you can download your binary here. And you did mention that homebrew and cargo install will be options in the future. Yes. Very soon. But, yeah, that's a good point. Yeah. You can download for your architecture directly from GitHub. Okay.

19:31 So we did that. We can now do dev. So according to the Grafbase CLI, we now have something running on port 4,001. So if we jump back to our browser, we get this user interface, which has loaded the schema and we can see that we have products. And if you're familiar with GraphQL, I'm assuming we can do product ID title. And on the right, we get a response. So that right in itself is just magic. So now we need to show people how that worked. Yes. So let's go through this. We have a graph based dot config. T s. And in this,

20:24 you're using the graph based TypeScript SDK where you're saying we want a standalone graph, an API as I just call it for now. You're then defining the types within this API. So you're saying this is a product and it has these properties, ID, title, description, and price. And then you're defining a query endpoint called products which returns yeah. And I I actually so you're just using the type. Right? You're saying you're returning a list of products and then has a resolver called products. And we're not gonna touch on authentication or anything like that right now, so we'll just

21:00 ignore this. And then you just export the config with your graph. I mean, that's the SDK in a nutshell. This is how you define what the API is, but there is a resolver that we haven't gotten to yet. And if I said they're incorrect? No. No. That's exactly right. I mean, they they just the point here is this is a code first approach. So we're using a builder pattern essentially to define your schema using TypeScript. Right? So there's two camps. Some people prefer schema first. Most people who are have built larger APIs use code first, but there's no right or

21:13 Resolvers and Edge Deployment

21:41 wrong. Yeah. I'm definitely an as code or code first person. Yeah. To me, it just resonates better. I guess one of the questions I I've got here is like these this way of describing a type is very Grafbase specific. Did you consider using any of the popular libraries out there like Zod or Tickbox or everyone that is the way to scaffold this? Yeah. We're we're actually we're working on opening this up so that you can use your own kind of way of building and defining your schema. So that's that's coming coming quite soon as well. So you could

22:27 use your own schema builder, GraphQL library, and you can then just use the output of that executable schema to deploy your and run your graph with Grafbase. Oh, nice. I like that. Okay. So let's get back to the fact that we ran a query and we got data back. This data comes from the fact that you have said that we have some sort of resolver, which is just a string called products. So this is one of the bits of what Grafbase magic where you correlate the string to a piece of code. Right? Yeah. Exactly. So we kind of use the

23:07 file system here. Right? So you have inside the folder resolvers, which is a predefined location. There's a products dot t s file, and that maps to the name products that you define up there. And it returns a static list of three products. Awesome. Now I guess this is just TypeScript code. So while a static array of data has been returned. This could quite easily be executing SQL queries against the database, MongoDB, other GraphQL APIs, REST APIs, etcetera. Like, this is where you connect Grafbase to your data model and make things work. Yeah. Yes. Exactly right.

23:56 And you can create as many resolvers as you want. Right? So what we do under the hood similar to, let's say, Vercel, is we take these resolver functions. We bundle them, and then we deploy them to its isolated to to a v eight isolate, essentially, so that whenever Quest comes in, it gets run-in in isolation. So it's really, really fast and low latency. Nice. And it definitely sounds like we could have an entire episode where we just talk about that deployment model and how you're doing that because there's a lot of interesting stuff there. But but focus

24:22 Introduction to Federation and Subgraphs

24:33 on the code aspect for today. So we have products. And then if we take a look at reviews, it's pretty much the same. Oh, they said they actually have they share a type. Right? Exactly. So this is another standalone subgraph, and then the different it defines re the review type, obviously. And what you do is you open up the product type, and this is where federation comes in. You can then say, hey. On the product type, I wanna add a reviews field, which then resolves from the reviews resolver in this subgraph. Neat. Okay. Let's get back to this because we've

25:16 got something over here. I removed the key here and the subgraph, and we still got an API that worked, resolved, that gave us data. So I wanna bring back each of these and talk about what that changes. So if we bring back subgraph true, what does this indicate to the Grafbase engine? What does it tell it, and how does it change the behavior? Yeah. So the if you if you if you enable subgraph behavior, you essentially expose two field two fields two clear fields that that are needed for for kind of federated queries to happen. Right? So there's a service

25:59 underscore service and underscore entities query in there that's that's that's required for this function properly. You could see it. And if you enable this and you open up Pathfinder again, Pathfinder is our, you know, in house GraphQL explorer we built. Does that real oh, that reloads. Yes. So if you refresh the screen I'll restart the Oh, yeah. You need sorry. Yeah. You need to add ID as well. Otherwise Alright. Okay. It it it needs at at least one key directive. Yeah. There you go. K. It detects the change, and we have to They use either. Yeah.

26:46 Okay. So what does the key do then? So if you go yeah. So the so the key essentially is something that is needed to correlate two types. Right? So if you wanna do you know, if you're if you're querying for products and you wanna get reviews, the the the gateway the federated gateway needs to know, okay. How how do I join these essentially? Okay. So you're kind of indicating that the ID is the primary key of this type. Yes. Exactly. If we go back to the reviews one, This also has an ID, but that's not

27:31 mentioned here because it just gets it from the schema itself. Yeah. Yeah. Because the, yeah, the the the gateway already knows how to resolve products from the product service, but reviews will come from the review subgraph. Okay. That makes sense. Cool. Alright. So I'm always curious just what's happening under the hood. Like, I need to see what these do. K. So this returns the STL. Go figure. And entities. This looks like something to do with Grafgel fragments, is definitely not my strong suit, but let's see what happens. I guess that does something different. Alright. Yeah. I don't understand what the entity's

28:32 endpoint is for. But I'm assuming that's just the way that the federated graph gets more information. Yeah. Yeah. It's it's a different way of introspecting a subgraph essentially. Alright. Okay. Gotcha. So if we you've already provided know why my alt tab keeps going to not where I want it to go. But you've already provided a top level package dot JSON where we can run PMPM dev, which will spin up everything together including the federation, which we haven't looked at yet. But let's do that dev. And what this is doing is running each of those graphs on their own

29:23 port, but the federation one will delegate requests for the types to the correct API, if I'm not mistaken. So I'm assuming gateway on port 4,000 is where we want to be. Yeah. That's my own API. So, yeah, so now this is a this is a clean slate. Right? So the federated graph has no no subgraphs. No subgraphs have been published yet. So the schema's empty. So now what you need to do is publish the product graph first and then reviews, and we can we can look at the the schema after that. Right. Gotcha. Okay. So let's take a look

30:23 at the gateway first and then we can publish to the gateway. So this also has a Grafbase config where we're saying that this is a federated one and there's no other there's nothing here that sells it where it's reaching out to, which is why the schema is empty. We have to publish each individual graph to the federated graph for it to be consumed. So if we come over here, we'll do product. And it was PMPM publish dev, I believe. Call on dev. Yep. K. That's right. This runs a Grafbase publish dev, goes to the name of products and tells

31:15 it where to find that API. And if we come back to reviews and do the same. May maybe first, maybe we'll go back to Pathfinder just so you can see the kind of the progression. So if you go to the schema page where you can see the SDL, there's yeah. There you go. So there you can see product and the query the products query. Right? One sub graph. Makes sense? Yeah. So we could start to query this now. Like so. Alright. So now you're in team b, and you wanna create your reviews subgraph that you publish to the federated graph without

31:58 touching team a's code base. So this is what this enables, essentially. So let's go back to schema, and now we have review. And, also, you can see on the product type, you can see the reviews field, which will then resolve to the reviews of Graf. And this is really Oh, we have a good idea. You've actually extended this type? Yes. Ah, I I didn't I didn't appreciate that from the the code. Let's look at that again. And then on the config. Okay. So team b has said, hey, We wanna add something to product, and we

32:44 wanna make our reviews queryable from it. That's nifty. I I didn't that that skipped over me, and I've got a nice little smile on my face now. So I like that. Yeah. These are the kind of moments that make you appreciate Grafge even more. Alright. So let's get reviews, and we'll get content and rating. Wow. Look at that. That's nice. And then, you know, as you see this, you you can then imagine, you know, engineering teams, two hundred or even thousands of engineers collaborating on a super graph or a federated graph in Synchrony. You know? And this is what

33:34 this unlocks, and we can we can look at things later. There's, you know, schema checks that is essentially something you add for CICD to make sure that what you're about to publish will be composable. And there's a linting, and then there's operation checks and all that stuff to make to make this more seamless for large teams. Okay. Now that you've made me smile and be confused at the same time, but I'm happy confused. I'm really curious about this extension point because one of the things I'm doing with the Rawkode Academy API, like I said, WebAssembly,

33:56 Extending Types Across Subgraphs (Live Demo)

34:12 Edge, and Rust, is that I'm trying to get into position where every like, it's not microservices. It's literally every everything I deploy is like a type. And rather than me changing or doing migrations, I'm using new services to deploy new functionality and then trying to bring all that data together at the front end, which is why I was interested in Grafbase in the first place. But what I didn't appreciate is that I could just take this type here. So I wanna I wanna copy your review service and tweak it. And I'm curious, can we add arbitrary

34:47 scalars to the product rather than a type preference? Would that still work? Custom scalars is still work in progress. It's coming. Oh, just well, if I wanted add a string or an integer. Oh, yeah. Yeah. Sure. I mean, go ahead and add. Okay. So one of the use cases I've got is, like, you know, say I have you know, I I model my YouTube channel on my on my type. So say I have something called a livestream, and then I decide I want to add a field to that livestream. I'm very much trying to be

35:17 very particular about not adding migrations. I I don't wanna get into migrations whatsoever. But I could do this with a new service that just injects, Say it was a thumbnail URL and I wanna add that. So let's just let's just do it and see if it works the way I think it does because that would be really cool for me. Let's copy reviews and we'll call this what else do products have? We'll call it link. Right? This is our link service. And I'll delete the Grafbase.Directrix. I think that may cause issues. I'll change this to be link

35:55 and I'll give it a new port like so. And we'll modify this. You wanna change the name too in the published script. The name of the subgraph. Alright. Let's get there. And I'm gonna do g dot string like this. And that you're you're saying this will allow me to enrich that type with a new value, which is very nice. Yeah. Yeah. I mean, you'll need a resolver. Mhmm. I mean, sure. In this case, it's just an empty string. You could do that too. But, typically, you have a you'll want a resolver to return some data for that

36:42 field. Okay. So link. I'll gokagi.com, Google Com, and we'd be remiss if we don't do graphbased.com. So this isn't going to be a review. This is now a well, I guess this is just going to be a link. Right? And Yeah. Okay. Well, I guess it depends what you if you wanna create a link object, which is typically I recommend doing that. Like, try to think of everything as types or entities rather than just a string. Okay. So we would have something like this. Mhmm. You know, just in the sake of completeness, let's not leave any sort of whole thing.

37:35 Does that change my config then? Or does this still Yep. Just have a reference to my link object. Right? Exactly. So you could you need to define a, up top, you know, a a link type, a reference here. Link. And I'll need to rename that fail. Link. So I need to type. Okay. Link. Alright. So with this resolver What's Is is it sorry. Is it a list or maybe you wanna omit? Is it just one link? Maybe I wanna omit the list or not. Yeah. It's just it's just one. Yeah. Okay. Yeah. So I guess what I I'm curious,

38:59 right, is how does it connect? Oh, yeah. Because you got the idea of key, but I'm assuming the link I'm confusing myself now. I'm wishing I hadn't gone down this path. This ID here, is this the product ID or the link ID? This is the link ID. Okay. So how does this resolver know to fetch links for the product? Yeah. So, you know, in the resolver function signature, you have four. The fur first thing is the root to the parent, and in there, you could then get the roots the calling, you know, types ID. So you could you could kind

39:43 of deconstruct here and just get ID if you wanted to, and then you can use that to fetch links for that product. Right? Okay. So let's assume someone's interest has peaked here. I I I assume they are for sure. And they wanna know how they work out what that signature is from the documentation. How how how do they get that? Resolvers on the left. Mhmm. Section overview. And here should be an example somewhere. Oh, yeah. Resolver function. Okay. Rx in context. Okay. Right. Okay. Got it. So I'm assuming this is kind of what we're trying to do

40:46 with the root and then extracting a value? Yep. Right. Okay. So we pull that to. So what's RxN? Sorry. So so I guess it like, you think about, like, root in this case, you have a product type. Right? So the link field is gonna get called from the product type. So root will have, you know, existing fields in there. Right? So you have the ID, for example. So that's gonna get passed in the root. Args is if you have query, like, if there were arguments to this link field, let's say I don't know. Maybe if Like, if we

41:34 touch something here where we said filter name. Well, but on the link on the link field, for example. Yeah. Like, that that would be for the product's resolver. You would get the args, and that's the second. Okay. So we can do something here equals root, and we're trying to fetch at the ID. And you said that comes I mean, would that just work? Yeah. Yeah. You could deconstruct it there or write in the signature itself. Yeah. You could do that. I'll leave it like this. Yeah. Sure. And I'm gonna get really nasty now. Right? So

42:12 if I d equals one, I'll assume it's gonna be a string. Yes. Which means we can remove the I d from our I mean, it doesn't really have to be a type now, but I I guess Oh, the link type is nice to have an interface up there, I think. Alright. I'll I'll remove the ID because I don't think we need to, and we'll just put URL. Okay. And we'll have URL. I'm sure people are watching me going, what the hell is this idiot doing? But we started. I I feel like I need to do

42:56 it. The first this is how database this is why they haven't even started many years ago. So alright. Now we don't now we could just return. You you get nothing. So this is a very crude resolver, and it's returning a link. Can I annotate that? No. Well, we we do we can look at this later if you want. There is a in docs, there is this code gen, experimental code generation that allows you to do kind of strongly typed resolvers. Well yeah. I was just curious because my interface is now unused. So, I mean, I can just do this.

43:45 But Yeah. Sure. You don't need to do it. So let's go back to my madness over here where we have a URL that's disappears and this gets resolved with our resolver. I I think you do need ID. Because of the key. Otherwise, the key will yeah. It will complain. But yeah. I mean, does it have to be unique? No. No. I don't think so. No. If this doesn't work, I'm very sorry. But I was following a train of thought. So But you need to also update the type definition in the config. You need to add

44:33 ID there to the yeah. Gotcha. And then in the before you publish that, go to the package script as well because it I think it has the wrong name. No. I changed it. Yeah. There you go. Oh, you did it. Okay. I missed that. Okay. So let's see what happens. So we can do a PMPM install, and we can add this. Oh, no. We don't have to add it because you're doing a global PMPM dev. Right? So I should be able to just do PMPM. I could check PMPM publish dev. Oh, yeah. It's probably just because it's not

45:38 started. Yeah. Okay. Yeah. Yeah. Requie the object not defined. It's still okay. What? Oh, yeah. You don't have a you don't have a query in here. But, no, you shouldn't have to. I don't think we have a query anywhere else. No. You're right. Alright. Let's see if my local check it out on my port. Right? So well, that might be an issue. Oh, no. There we go. Oh oh, I I know what happened. You you actually stopped the whole thing. Right? So if you stop it, the in memory representation goes away in local devs. So you need

46:34 to start over. So you need to, you know, publish products, reviews, then link now that everything is running. Right. Okay. We don't persist the the state. One link. Oh. Okay. I'm just breaking everything today. There we go. Alright. Here you go. Well done. Complete It worked. Random tangent, but that is super powerful. I am so happy and impressed. And I had no idea that feature existed whatsoever. So, yeah, that's amazing. Alright. Thank you for entertaining me. Let's get back on track. So that's usually powerful. And let's focus on that use case just so that it's really cement that into people's

47:51 Benefits of Federation for Teams

47:59 heads. You're working with a whole bunch of teams. You're all working towards one API and, you know, traditional routes would be we all build our different REST stuff. We stick an API gateway in front of it and then we hope that everything works together. But what Grafbase is doing is different. The teams are independently working on their own small little part of a made global graph, their own subgraph, to find in their own types, their own resolvers, and we're getting data. They can then take their graphs that they're happy with, they've tested, all good, they publish it,

48:34 and the federated graph starts to pick all this up. And we actually seen that in in progress. Right? We published one. We checked the schema. We published one. We checked the schema. We're enriching it all the time. Then there was the tangent. Okay. We realized these subgraphs can actually extend other parts of the graph. I'm assuming there's a schema registry that if my link service tried to add ratings or reviews, we would get that error during publish and say, sorry, you can't do this. This this already exists. That workflow has gotta be an enabler for teams. It's

49:10 gotta be able they've gotta be able to increase their velocity. They don't have to worry too much about stepping on each other's toes because the graph consolidation, the schema, all of that works together to give them something that is guaranteed to be correct or it'll fail to publish. Again, I don't wanna put words in your mouth, but does that sound correct? Is that what's happening here? Absolutely. I mean, it it's it's exactly right. It's built with this very use case in mind where your team evolves from one monolithic code base and graph into multiple subgraphs. And

49:45 it's really, really nice to have some guardrails around that and during CICD catch issues so that when it goes to production, you have confidence that it should work. You know? Okay. You mentioned CITD. Well, I think that loops us nicely into let's get this into production. And, we could repeat those published steps that we've done, but you actually have an integration with GitHub to automate this for people. Right? Yes. Exactly. Okay. So I guess the first thing I need to do is, you know, we can stop testing this. We're happy with it. I'll even just kind of

50:02 Deploying to Grafbase Cloud (GitHub Integration)

50:30 shut this window down. We're in the top level. I can just do my YOLO commit. In fact, my workspace, has that got a wildcard in it? Yeah. Cool. I was wondering how that worked there. We could do get in it. Get at ship being dot one. Right? This is it. We're gonna start making money. And I can push this. Remote l s. Oh, list. Why can I never remember how to do that? Don't know why I bother trying to use the get commands. So this is your upstream which we don't need and this is my federation. Okay. So we

51:22 can do a get push origin main. Now, that's not gonna do anything by default yet because we've not hooked anything up. But if we do go to GitHub, I've got my ship b one here. Shall we use the the Grafbase UI to connect this all up and deploy to production? Let's do it. So let's sign in and create project. I'm gonna have to adjust my permissions. Federation demo. So I'm just given the Grafbase application access to what we need. Here's my passkey. Such a nice upgrade passkey. Yeah. 100%. Let's give this a wee refresh. There we go. So I could just import

52:40 this repository. I've never done this before, I don't know what this looks like. Yeah. So the two things to pay attention to. One is the name of this. Because I think the first thing you wanna do is the gateway. Right? You probably wanna give it federation demo dash gateway or just the gateway. Mhmm. And then the root folder is gonna be dot slash apps slash gateway. And that's it. If you have any end bars, you can add them here, but we don't. So go ahead and deploy. Nice confetti. Confetti. Yeah. We gotta celebrate. Alright. So let's So now Should we take

53:23 a look at this? Oh, we don't get Pathfinder or do we? Yeah. It's in the dashboard. It's not Oh, yeah. Oh, yeah. Sure. Okay. Yeah. Yeah. Well, okay. We'll give that a second. So if you gotta it's it's usually quite quick. I'm surprised it takes this long. There we go. There you go. Okay. Yeah. Empty, say, no nothing in schema yet. And then go ahead and go to the home account overview and then create three more, I guess, product reviews and links. K. So product apps product. Let me just copy that for next time. And

54:08 reviews and links. Nice. So this is oh, let well, let's come back to that. Was wondering. Right? This is obviously connected to get there. So if I do get pushed, it's gonna do updates. We can confirm that in a minute. If we come over to our gateway I'm assuming right now we we still don't have any yeah. So how do we how do we see we're happy with our subgraph? We wanna publish it to the federated. Right. So what you wanna do here is you go to the overview there, the left tab far left tab, and then you can see

55:12 the subgraph section. There's a snippet there. You can you can copy. Yep. And then but what you need first is the schema STL. Right? So this this is typically something you do in the CICD, not in the terminal, like, one ops. But for the demo, let's go ahead and do that. So what you wanna do is Yeah. Go to the products of Graf overview in the dashboard. Oh, yep. I I open a new tab or something. Okay. Fine. Go to the products one, and then copy the URL. So take the one the the bottom one.

55:55 Yep. Yep. And then you go in the terminal. You can do GB, just an alias install introspect. GB introspect or the Grafbase introspect, and then you paste the URL. So this shows you the STL here. So you'll pipe that to schema or, yeah, STL dot GraphQL. It's fine. And then you go back to the dashboard for the gateway, and then you copy that snippet. And that's how you you wanna replace the the name. There you go. URL is the one you use above. And then give it the product's name. That should be what you need to publish

56:55 the first subgraph. Oh, yeah. Okay. Oh, because I I copied the MPX. Oh, yeah. Yeah. Okay. Alright. So let's refresh this. I don't even have to. It's already showing up, but there we go. We now have our subgraph. Yes. Okay. Maybe? Interesting. So so what happens is Oh, there we go. Registry. Yeah. There is the registry which triggers the deploy. So if you go to the change log tab, you can see what you just pushed here. And then if you go to the deployments tab, you'll see that the schema registry enabled another deploy. There's a deployments tab there. There

57:48 you go. So you can see that, you know, the registry initiated the deployment. Once the deployment is done, you see the updated version. That This happens every time someone publishes a new schema. Okay. And I'm assuming there's a GitHub action to automate that in a a workflow. Yes. Exactly. So another thing we haven't touched on is checks. So, typically, you run a schema check if there's a checks out there, which is essentially kind of linting operation checks, that kind of stuff you can do, but I don't think we need to go into it now. But typically run that,

58:27 assuming it's good, you then go ahead and publish it. Otherwise, the check becomes red, which means there's something wrong with the the schema you're trying to publish. Nice. Very, very cool. I like this. You also provide analytics, and I've seen in the documentation earlier, there's authorization and caching as well. But Yeah. There's a lot that Grafbase is making your life a lot easier if you wanna build out a GraphQL API. That that's the goal. I I think edge caching could be potentially another episode, but it's it's it's super exciting, I think. Because if you think about

58:41 Additional Features: Caching, Analytics & Dogfooding

59:10 the fact that you have compute that's globally deployed, the caching layer comes with it. Right? So you can really, really quickly, like, get cash response times for everyone in the world. Right? So ecommerce, travel, logistics, some of the kind of use cases that use Grafbase to speed up response times, but also to protect their back end. You know? It might be using a third party vendor that's legacy or slow, but you're doing this lookup constantly. Caching can really help there. Yeah. Very nice. I'm curious. There's obviously the Grafbase API itself. I I guess you build up a Grafbase.

59:58 Is that right? Or should I not ask that question? We're yeah. We we we no. No. No. You should it's it's a really good question. We we are we are we are in in on the we're in the process of dogfooding it. It's not really quite there yet, but we will get there this year. So Grafbase will be built on Grafbase. And the reason is because we haven't enabled support for yet as a customer of Grafbase. So we're building a Rust, obviously, and we don't support Rust resolvers yet. But when we do, we will be able to.

1:00:34 Experimental Feature: Key-Value Store

1:00:34 Okay. Awesome. Alright. We kinda took a bit of a tangent with my link syncing there. But, you know, we still have a little bit of time left. Is there anything you think would be worth showing to people before we go back to the the talking and questions? We never really did connectors. Yeah. We can we can maybe glance at them. We could maybe try one if you want. But we do have, like we said, the concept of connectors and you know, essentially, all APIs are just data passing. Right? That's really what it is. So we we

1:01:11 we saw this pattern of connecting a data source, exposing fields in your API schema. It's quite repetitive and mundane, so we build connectors that introspect your schema and then generate the API schema for you. Depending on the quality of that schema, it can look really great. Sometimes it's a bit more awkward. You know, open API can really vary, so I would say some of them are good. Some of them are not so good. But what we typically see is people use what they can to generate, and then they can extend and customize with the configuration file like like we did

1:01:52 in the in the subgraphs. So that's it's a really nice kind of way to just speed up your time to market. Nice. Yeah. I think a good example here is obviously you can connect us to GraphQL. But, you know, hooking it up to Postgres or MongoDB and getting that not having to worry about those resolvers as a that'd be big time saver for people. I like that feature as well. Yeah. Alright. Let's Maybe we could just feature or highlight some of the experimental stuff. We have KV, which is a kind of key value store. It's built in to the resolvers.

1:02:28 It's globally distributed as well. So you can use that to kind of store things or, yeah, use it like Redis, but it lives at the edge. It's pretty cool feature. Alright. Let's be brave. Let's do it. Yeah. Alright. Let's go here. So and no. We shouldn't do it. Let's just let's replace my link service because, you know, it's pretty useless anyway. So we have to end the config, enable k v. Like so. Now, I'm assuming we could add some sort of wouldn't be type. Right? We'd add a mutation to store a value. Store store a link. Right?

1:03:24 Yep. Look at this. Copilot's trying to get on board here. Let's see how close it gets. Right? So let's use the documentation. We want to do a quick start, And this has given us a resolver function to get. So let's go to set and we get this. So copy And I'll just leave this here. Yeah. We don't support inline resolvers just yet, but it's coming. So you need to create separate resolver files. Yeah. This has to go in a resolver file. Right? Yeah. Yeah. Okay. For now. Okay. So we'll just call this set dot t

1:04:09 s where we export and we know that we could pull in this route and we can get the product ID. So we'll use this as the key and the value I'm assuming would be an arg. So we need this. Yep. And this would be arg, and we'll just call this URL. Not sure if that's gonna work, but I think that looks okay to me. Well, I think I think both both. The key will be an arg too. Like, you have an input arg. You know Oh, yeah. Yeah. Object itself or you have two input arg key value.

1:04:58 You're right. Yeah. Because we're not this doesn't gonna be it's not we're not in line of a product. This is a mutation query. So yes. Yes. Which means this now looks a bit silly, but whatever. It's okay. So if we go back here, what I'm not sure is what this mutation looks like. So I'm gonna see, is there an example rather than asking you to get it from your head. Mutation resolvers. There we go. And we'll call this create link. And we said that it needs an ID and a URL. Like so. And it returns.

1:05:49 We actually haven't said what returns, so I'll just leave that as it is. And we called it set. So, yeah, what what is the return here? Is that just because we're just in a k v set. Should we be really returning the value? Or Yeah. Sure. Alright. I mean, it doesn't really matter. Yeah. Okay. I mean, if the if it's a typically, you return, like, you know, the payload and there's a type within there and if there's any errors. But for now, you know, keep it simple. Okay. Well, we're we're just hacking this together to test out the KB.

1:06:25 So let's go to our dev experience now. So we're going back to link and what we want to do is PNPM dev. Hopefully, it's not broken. Seems happier than I expected. And we go to path. Oh, my camera just went off. I wonder if it said battery exhausted before it did that. Let me grab my foot. Okay. Better. Okay. So we don't have anything here yet. So what did I get wrong? Well, it's a mutation, so there's a set a separate tab in the in the UI. You see the Oh. Mutation. Here you go. Alright.

1:07:48 One. Grafbase dot com. Do we just execute that like so? Oh, yeah. And that's the return value. Right? Mhmm. So now And just while you do that, you know, part of the DX you want to achieve is you don't have to think about infrastructure. You didn't have to brew install Redis or set up any YAML files or anything. It just works. In development and in production, you have KB store. So I guess we'll need to write a resolver to do the k v get. Right? Yes. You can hook it up to the one you have, I guess. Right?

1:08:48 Just need to Oh, yeah. So we yeah. We call this length, so then modify that resolver. Okay. And that's what need to be a ref link dot list. And then if we come to link, let's take a look at the set example. We can swap all of this though and do a get key as long as we provide arg or expand this for key. I think. Challenge will be I do know IT and URL is what we do in the set. Right? Yep. Let's remove this product. I don't know. How are you feeling about that? Confident?

1:10:01 Yeah. Absolutely. Alright. So it's just compiling, reloading. Alright. Let's see. Sure. It's my fault. Alright. Let's walk let's step through it. We have a type, we have an ID and a URL. We create something here. We have a query. So I'm assuming my k v get is a bit wrong, but I made that up. So that's probably fair. Let's come back to k v. And I guess it's a list. No. There's a guest as well. Okay. That's the only one. Right? Yeah. There I mean, it returns. Might need to destruct. Oh, no. The problem is then I'm

1:11:19 doing a get, but my thing here was to return a list, but it's actually just gonna be one link stored at the key. Right? Mhmm. But I think you also need to think of the return. Like, you need to destruct like, look at the example and docs and what you're doing there. You're just returning the whole thing. You need to, like I guess I need to return the type with the key and the URL with the value. Well, you're it's expecting a string, isn't it? Or did you change that? Oh, no. Sorry. Sorry. This is the get.

1:11:54 This is the get. Yeah. Yeah. I mean, we could update we could update the mutations also. You're like, don't touch anything. Just make it work. Alright. That's okay. Alright. Let's let's see where we are now. Pathfinder. But I think you need to, like, destruct the the return still. Missing. Okay. On the resolver, you mean. Right? Yes. In the get. So The Let's talk about the debugging. Can I just do this? Yeah. Yeah. I mean, you can if you add a try catch maybe, you can see what's going on. You need to add like, if you look

1:12:52 at the example, you need to add a curly brace around the value, like, const before value. Like that. You see? Yeah. Okay. Gotcha. Oh, we probably don't need that until we load. It's really bizarre. If you could you add a try catch around? Oops. I wonder if it's just delayed. Like, it looks try try rerunning the whole thing, and that looks bizarre. Yes. I will. Is there any sort of verbosity on this? Yeah. I mean, it is you can. You can add if you wanna see debug stuff, I mean, like, internal, you can add trace trace too, but that's pretty verbose. So

1:14:06 you should see. Let's try this. Oh, wait. That's in the wrong bit. Yeah. I know. Okay. And a restart is not gonna hurt anything. So let's get that back up and running. Go back to Pathfinder. No. I've done something wrong. Okay. The the other try catch around the whole the whole like, from the start of the resolver to the end. Oh, I know what's missing. Sorry. I was blind. So if you you see the examples, you need in the context object, you have KB. You need to get it from somewhere. Like, look at the docs. You know? See

1:14:57 what I mean? I see it. There you go. That'll do it. I was wondering why it was, like, red under. So now now I should have just copied this whole result. Yeah. That was my problem. Oh, wait. Well, there's nothing to get yet. Right? So let's bring back our mutation. Just a try. We'll just debug this for one more minute. We don't need to get it working. It was just me on the web. It's all good. Console dot log e. I'm gonna do a restart just to give it the best chance. Although I don't think

1:15:55 we need it. And let's hit the create. I'm gonna do that again to see if we got an error. Although, I guess it didn't set over the top. Oh, okay. That's a different error. And error code of infection links, a non nullable value which is expected, but no value was found. So that tells me Yeah. This is okay. So I'm calling a get when we should be doing a list. Right? Well, list returns everything. Yeah. But we're doing a a get. So our resolver expects there to be a a key. And are you passing the key or is

1:17:01 it called something else? Is it called ID maybe? Well, I wasn't passing a key. So that will be the problem. Okay. But if we if we do this as a list. We need to map it to the Ah, yeah. Okay. Let's Okay. Let's just give it the right value. So we need to send. And again, you should ID or key. Well, we haven't built this into the we haven't oh. Sorry. I'm here to say that as a familiar here. We actually haven't built any sort of query that takes a parameter. So we need our Oh, okay. Thank you. This

1:17:50 gives us an ID. And if we update our resolver, we don't want a key. We want an ID where we get an ID and we return an ID. See, these things are really simple when you're not just me being a bit gunhole with a typey typey. So Yeah. If we let all of this restart, we should see that our schema changes. Yep. So let's call it our create. Tom is in the chat telling us that we're Yeah. Sorry. Hey. Hey. Thanks, Tom. So this needs an ID one. There we go. There. So that was a a long way

1:18:46 to show off your k v feature. Finally. Well done. Yeah. It is a really cool feature and we're not gonna go into the AI stuff now. Not not with my ability to type code, but you do have all of these AI services available with a bunch of language models, which is very, very cool. Access to OpenAI Whisper, Llama, and I'm not familiar with these ones, but very cool as well. Alright. Let's get back to big face mode. Sorry. I'm not gonna type any more code. I can't be trusted. Oh, where'd my camera go? Oops. There we go. Alright.

1:18:54 Roadmap & Upcoming Features

1:19:33 Yeah. From Tom. Yeah. Thanks for hanging in there, Tom. Thanks for your help. I'll just reiterate. Right? Very cool platform. Makes building GraphQL APIs easy as long as you pay attention to the docs and don't try and make it up. The ability to hook into a key value store is very, cool when you want, you know there are probably a lot of use cases where you could survive on that without having to reach out to resolvers. I guess it also provides a nice cache in there, but there's already a whole bunch of cache and stuff that Grafbase provides if you go and

1:20:03 explore that in the documentation. We've got connectors for Postgres, MongoDB, other GraphQL APIs, and more. I think, you know, we've we've shown enough. I'm assuming people's interest has peaked. You've already said a few times during this episode, there's more coming soon or this is coming soon. So can you in the last few minutes, can you give us an idea of what the team are working on just now? What are the challenges you're trying to solve? What can people expect over the next three to six months? Absolutely. So well, the news of this week is we are

1:20:35 launching a brand new version of the dashboard. It's something we've been building for a while, Complete redesign, new stack. We're really, really happy with it. We're just figuring out the last pieces. That's coming very soon. Watch out for that announcement in Discord and Twitter. We just we are investing quite heavily in analytics and security right now, so we're gonna have a bunch of things like field level analytics, tracing. That kind of stuff is coming quite soon as well. We just launched automatic persistent queries, which is a kind of performance optimization to avoid sending the operation payload over and over.

1:21:19 And then soon, we're launching something called trusted documents, which is essentially a security enabler where you can say these are queries and mutations that are allowed to be made to this graphical endpoint, and everything else will be rejected. We just launched the ability to kind of disable introspection, which is also quite common in production as a security precaution. Batching is coming soon, rate limiting. An HTTP connector is coming. So where you might not have a schema, we're gonna enable you to just write a, you know, simple kind of mapping connector to a REST API or otherwise

1:22:00 that doesn't currently exist. And I think that the the biggest thing we're working around is the ability to self host Grafbase. Right? So there's two kind of things there. One is a hybrid approach where you deploy the gateway itself in your infrastructure. It's quite common among enterprises. But the rest kind of tracing, observability, security is hosted by us. And then lastly, the ability to deploy the whole platform in your own infrastructure is it's a big big undertaking, but it's quite, popular among federal and and and the likes who might not have Internet or they don't

1:22:39 want Internet. So that's also coming. Awesome. Lots of amazing stuff there, and, I'm very excited to hopefully see, SQLite connector. Yes. And that's also on the road map. I forgot to mention that. We are connectors take quite a bit of time, especially database ones. Like, we spend a lot of time building the Postgres connector. We actually have some of the core team from Prisma join us to to, to build some of these the Mongo connector and Postgres connector. And even with their experience, it took took us quite a while to to build one that is performant and scalable and avoids

1:23:20 n plus one queries and all that stuff. Stuff. Yeah. Tough tough challenges, but I'm glad you've got good people working on it. Like you said, hire hire the best engineers and you build good software. Yeah. Alright. Well, thank you so much for your time today and your patience as I was going a bit hacky on things. But I hope people enjoy Grafbase. Go check it out at grafbase.com. As a reminder, that is grafbase.com. Any final words, Frederic, before I say goodbye? Thanks so much. You know, GrafQL is better than Rust. That's all I can say.

1:23:32 Conclusion and Farewell

1:23:54 We'll end on that note and then hit or set the comments later. Alright. Alright. Thank you all for watching. We'll see you all soon. Have a good day. Bye. Thanks so much.

Technologies featured

Meet the Cast

Weekly Cloud Native insights

Stay ahead in cloud native

Tutorials, deep dives, and curated events. No fluff.

Comments, transcript, and resources

More from Rawkode Live

View all 173 episodes