 I think we're going to go for it, and all of you here now, the last day of DrupalCon at 8.30 in the morning, you are the true heroes, so where'd it go? Yeah, so this is Drupal State and the need for a JavaScript SDK, so hopefully you're in the right place. I am Brian Perry. I am a Senior Software Engineer at Pantheon. I'm also the Initiative Coordinator for the Decoupled Menus Initiative, which we've been working on trying to kind of bring to a conclusion at contrib events this week. I live in the Chicago suburbs. I like Drupal, JavaScript, and Nintendo, and I somewhat recently bought a replica Ms. Pac-Man machine, which I have in my office and I'm still very proud of. I have a website. I'm on Twitter, which although now is a horrible wasteland, and I'm also on Drupal.org, and feel free to get in touch. As I mentioned, work at Pantheon. Look at this great internet image loading here. Yeah, I want to thank Pantheon for sending me out here, and also especially for allowing the time that I've had to contribute on some of the things that we'll be talking about today. A lot of the projects that I've been working on in support of Decoupled Sites are either currently open sourced or will be open sourced, so it's been really exciting work and I'm looking forward to what we have in the future. But today, we're going to be talking about a specific library called Drupal State that is a general project on Drupal.org, it's published on NPM, it is a simple data store for managing application state source from Drupal's JSON API. We'll talk about what that means, why the library was created, why somebody might consider using it, and then also why I think this library or something like it is important for the future of Drupal. But also, we are going to take a winding journey through the Drupal-related JavaScript ecosystem as well, so buckle up. We'll also look at some code examples along the way, starting with this one, which is a menu web component. So I talked about the Decoupled Menus Initiative before, so there's a new endpoint that's going to be going into core that exposes menu data and as part of the hackathon last year at DrupalCon, a number of developers got together and tried to create different components to consume this data. So this is a web component that was created as part of a project called GenericDrupalWebComponents, if we take a look at this here, we'll see we can expand the menu and there's menu data that comes in from Drupal. The JavaScript file here, it's just importing the component itself and a style sheet. The markup is where most of the magic happens here, so this is a custom element GWC menu in this case, and we're passing in some different props, the branding for the title of the menu, and then we have the base URL of our Drupal backend, so that's how this component knows where to source its menu data from, the menu machine name, and then a theme attribute as well, so we can change some of these things. So if I take out the theme, it's unstyled, it's just an unordered list here, but still has all of the menu hierarchy. If we change the menu ID to the account menu, we'll see that it pulls the account menu, and since we're not authenticated, there's just the login link. But the idea here was to try to build something that really makes it as simple as possible to consume a particular set of data from Drupal in a web component like this, and how that happens behind the scenes. I can transition here. So the component itself is actually responsible for fetching the data. Web components have a handful of different lifecycle methods, this connected callback is one of them, it essentially runs when the web component mounts, so it runs a fetch data function, we provide the URL and the menu ID. So this is the code for the fetch, nothing super complicated here, it kind of constructs the endpoint that needs to talk to you on the Drupal side, and then uses JavaScript fetch, and then also the menu response follows this link set spec, so there's a supporting library that's used here to parse it so that it can easily represent the hierarchy and can be more easily easy to work with on the front end. So that all works nicely, and that's abstracted away from it's embedded inside the component itself. However, after building that component, the next thing that I started looking at was can we make other components like this? And that approach definitely does not scale, so the first thing that I looked at is making a card component, and for one card, having the logic inside the component to go make a request to Drupal is fine, if you got 10 of them, that's 10 different calls, and 100, you got potentially some serious problems. So that led me to thinking how could there be something to support that type of problem? So from my perspective, this component library needed utilities to make it easy to source data from Drupal's API end points, and then something that would allow that data, that application state to be managed across this component library and shared across different components, including ones that we haven't built yet. And that seems like something given the work with Drupal and the excitement around that, something that I would have expected to be a mostly solved problem, and for there to be things I could magically npm install to do it. So I looked at projects I was familiar in some cases not familiar with in the general decoupled Drupal ecosystem, to see how they handled it. So there is Drux, which is a view project, and that has its own custom JSON API client. It uses Axios to fetch data. It uses a Vuex store, which is a view state management solution. The next for Drupal project, which you may be familiar with, and there's certainly been a lot of talk about this week, they just recently had a major release 1.3 major in that there were some pretty substantial changes. Before 1.3, it also had its own set of helper functions, and didn't really have much of a opinion on state management. The 1.3 release introduces a Drupal client. There's actually quite a bit in common with what that client does and this library. I think we've all just kind of been looking at what all these similar projects are doing and how we've been solving this problem. And it also has the ability to essentially provide your own caching mechanism. So it's pretty easy to bring your own thing, but it doesn't necessarily have a default opinion about it. There's a handful of other Drupal SDK-like libraries out there, Drupal SDK, Drupal JS SDK, all some of them in different levels of activity and maintenance. And then for just general, a couple of projects, oftentimes from my experience, the code for this is custom, and they roll their own solution. They might bring in their preferred state management library like Redux on a React project, and there's custom code written to fetch data from Drupal. It's not the most complicated thing in the world, but it's also something that is essentially getting written over and over and over again. So I wondered what would need to be created to prevent this problem from being solved over and over and over? And from my perspective, it would have to be something framework agnostic. So it could be used with Vue or React or Svelte or the JavaScript framework that's super cool in five years. And then it also should have the ability to, it should be possible to use the individual utilities within it if somebody just wanted to use a piece of this in their project or in another Drupal ecosystem-related project that should be able to do that. And although I think it is useful for people to be able to still use something like this with their preferred state management solution, I do think there would be value in a library like this that essentially has a default starting point for that, a default answer. And then I also started thinking about just JSON API itself while I was kind of brainstorming all of the world's problems here and wondering could working with JSON API be friendlier for JavaScript developers? Specifically thinking about developers who might not be familiar with Drupal or might not be familiar with the JSON API spec. And Drupal's JSON API modules and JSON API ecosystem is amazing and it really can allow you to easily get data out of Drupal with limited configuration. But as we'll see here in some of the things that we look at, there are certainly some things that you need to know going in or learn to be able to interact with it. So let's actually just look at some examples of how you could write some JavaScript to get data from JSON API. So we're getting recipes here, the demo mommy data, you may know what Drupal's recipes endpoint is for your Drupal installation. However, at the root of JSON API, there's essentially an index of all of the different API endpoints that are enabled. So if you don't know what the recipe's endpoint is, you would hit the root of JSON API, get the response back to understand what the API endpoint that you need to reference to get the recipes is. And then you would need to fetch that endpoint to get all of the recipes. So then we have all recipes under recipes from API.data here. And if I wanted to print out the instructions, if we start to look at the data that we get back here, some data is at the top level, other things are under attributes. So if I wanted to print out the instructions, that would be under attributes.instructions. And we'll work a little bit more at this in a few examples. But things that are like referenced entities in Drupal in the response here are under relationships. And by default, we just get the ID here. So there's some additional work that we'd have to do if we want to get information for referenced entities. And then let's imagine that we have, we got all of the recipes. And then later, we want to just get one of them or just work with one particular recipe. So we could make another request to JSON API for that specific recipe with the ID that we have that would be a somewhat redundant request because we already had that data. So alternatively, we could do something to store that in a variable or in some sort of state management solution. But we would still have to go back through that, find the item at the particular ID to be able to have a representation of just that recipe. And then this next example here, if it will let me click to the next thing, there we go. So this is an example with a reference entity. So the recipes have taxonomy term for category. So let's say that we want to get the category for a particular recipe. In this case, it's snack. So basically, what we're trying to do here is get snack on the screen. JSON API has a number of query string parameters that you can provide. So one of them is include. So we can say that we want to include the category, we just pop that on to the query string in the JSON API request that we make. And then in the response that we get back, we'll see that there is a new section here included that has all of the included relationships. So there is a section that's going to have all of the categories and the category data. So if we wanted to, you know, print this particular category on to the screen, we have to, we'll have the ID in the main response for the entity, the ID of the category under relationships here. So we'd have to get that ID and then we'll have to, in the included portion of the response, look up the category by that ID to be able to pronounce the category. So, you know, at the end of the day here, the category name here is, you know, category, the first item in the array, because there could be multiple categories.attributes.name. So a long walk to put snack on the screen in this case. Another common problem that I've seen with the use of JSON API is overfetching data. So by default, JSON API will give you all of the data for, you know, a particular resource. So if we had like a grid of categories and we were just showing teasers, we might only need like four or so fields, but you're going to get way, way more than that. And for large data sets that can have a really meaningful impact on the payload, JSON API also supports this. So, you know, we already added this include category. We can also put query string parameters to dictate the fields that we want to get back in our response. So we can say, fields, recipes, title, difficulty, instructions, and category if we wanted those. That's still not quite enough though, because we will get back all of the data for the categories if we do that. So still a lot more that we need, especially if we're just printing snack on the screen. So we would have to say fields, recipes, list out all those fields, and then fields, categories, and say that we just not want the name. So totally possible to do that with JSON API, but, you know, you have to be familiar with the, you know, the spec Drupal's implementation of it. You have to construct that query string when you make your request. There is a library out there, a great library, Drupal JSON API params that provides some helper utilities to make that easier adding those query string parameters. But, you know, you have to have had found that library somehow. Okay, so this is the, that constructed response with all the query string parameters that we need, we're fetching that. But, you know, the thing to kind of call out here is that even when we're very explicit about what we want and what fields we want, the shape of the response still might not be, you know, what you would assume, you know, based on some of the things that we looked at before. Some things are under the attribute section of the object. There's still the relationship section and we still have to go into included to look up the category. So even though we basically said I want these four fields, it's certainly not that clean in what we get back. So going back to over fetching, there also is the GraphQL of it all. For those who might not be familiar with GraphQL, it's an alternate query language that's pretty popular in the JavaScript ecosystem. And it's good at solving this problem and preventing this type of over fetching because you essentially define the shape of your query and then the response that comes back essentially follows that shape exactly. And so with Drupal, I personally haven't done a ton of work with GraphQL and the contributed GraphQL module, but my understanding of kind of where that's at in the Drupal world right now is so GraphQL is not part of Drupal core, it's a contributed module, JSON API is part of core. And then also there has been a little bit of maybe even say growing pains going from the version three of GraphQL to version four in that version three works kind of a little bit conceptually like what JSON API does in that it kind of automatically exposes all of your data. So version three would automatically generate a GraphQL schema so that you can just start querying all of your Drupal things. However, that means that that schema kind of comes along with a lot of Drupalisms. So for version four, the change was made essentially so that that schema is not automatically generated by default, which means that it requires custom code to be able to essentially have a GraphQL API, but it'll be more tailored to your use case. Jesus on the octahedral team, a good friend over at Pantheon, he's currently working on solving that problem and making some great progress there. So hopefully that will improve soon. And version four will have some more flexibility with that as well. So keep an eye on that. But complicated to parse all that. So finally getting back to Drupal states and the attempt to solve some of these problems. So how this library tries to do that, it's a framework agnostic. So it's vanilla JavaScript and you can use it with all of your favorite frameworks. It's universal, it can run server side and client side. And at the highest level, what it does is it gets an object from Drupal's JSON API. And then it'll serve all future requests for that object from local state. So if you request a JSON API endpoints and we don't have that object yet, it'll fetch it. But the next time that you ask for that object, it'll get it from state or it'll try to get it from state first. And it simplifies the response back. It deserializes the response by default. We'll see what that looks like. And all of the underlying utility functions are also exported so that it can be used individually. So if you just wanted to use some of the utilities to get data and you didn't want to have this particular approach to state management or local storage, you don't have to. So let's look at essentially the same examples, but what it would look like using this library. So first you'll need to import it. And then create an instance of Drupal state. We create our store. So we provide the API base. And then we can provide our JSON API prefix. By default, that's JSON API. So if it's not a different API prefix, you can just leave that off. There's some debug methods that you can enable to get more debug output. But then to get all of the recipes, we can with the store, say, store.get object, and then provide the object name. So that's essentially the resource in the root JSON API index. So when we do that, we get back all of the data for the recipe. And then if we were to make here another request for a particular recipe, we can also provide an ID to that get object method. It will first check the local data store to see if that recipe exists. It does because we already got all the recipes. So just return it from state rather than making another request to JSON API. And then if we look at the shape of the response here, it's deserialized and a lot flatter. So most of the things are at the top level. There isn't things under the attributes object. And we'll also look in a second how reference entities kind of fit into that. Okay. So this next example here is, yeah, what we looked at before with getting at the category for a taxonomy term or reference entity. So this Drupal state does use that Drupal JSON API params library as a dependency. So we have helper methods for adding all of the different JSON API query string parameters. So we can say params dot add include category. So that's going to say to include the category data. And then if we get a particular recipe, the response that we get back, again, it's deserialized and flattened. So if we scroll down a bit to the category, it's right at the top level. And also the category data is deserialized as well. So if we want to print out, in this case, salad on the screen, it's just recipe dot category dot name. And we don't have to kind of climb through it to find our referenced entity there. And then this is an example of an additional utility. So we're trying to also provide utilities for some of the popular modules within the JSON API ecosystem. One of them is decoupled router. So that allows you to provide a path. And decoupled router goes through, you know, any necessary redirects to try to resolve that path to an entity in Drupal. So we have this get object by path method, which you can provide the object name and also the path. And if we have the path for our fiery chili sauce recipe, we get back the data for that particular recipe. And then this is an example of using the underlying function that does that work. So if you didn't want to use the state management piece of Drupal state, but you found this particular utility useful for working with decoupled router, you could just use this translate path function. So you can import translate path from Drupal state, and then just call that function. And it takes in your decoupled router endpoint and the path that you want to get. And this just gets the raw response in this case from decoupled router. And this is a look at the code for that function. You know, it's certainly not that complicated, not a whole lot of code here. But, you know, why write this over and over if this is a utility, you know, a solve problem that could be helpful for you. It basically just constructs the necessary query string primers that have to be passed to decoupled router. And, you know, it's able to use other utilities from this library. So there's, you know, default methods for fetch that we use a library called jsona for json API typescript types. Yeah, so, you know, this is an example of something that, you know, not the most complicated thing to write. But, you know, maybe you don't have to write it. And this is kind of getting into a feature that I still consider a little experimental at this point. But, you know, we talked about GraphQL and also that, you know, that's kind of a common and popular approach to querying in the JavaScript ecosystem. So there's an additional feature here where you can provide lightweight GraphQL queries in your requests. So we have this query here and we provide the title difficulty instructions and then category name and the response that we get back as we see on the right really clean and, you know, just follows the shape of that response. This is using a Apollo client and Apollo client has the concept of a link, which is basically something that kind of stands in the middle in between your API and your request to the client and can do things. And there is another package out there that actually provides a translation layer in between json API endpoints and creates a GraphQL schema, which sounds like magic, but as we see here, it does work. So the reason this is experimental, in my opinion, I think we just need to put this through its paces more to see where the limitations of it are. It also depends on the GraphQL anywhere library, which I believe isn't being actively maintained. So we'll need to figure out if there could be a replacement there or exactly what that would mean having that as a dependency. But yeah, I think this could be, you know, a nice developer experience nicety here. The other thing that this actually does is because we get the query and, you know, essentially the developer here is describing the shape that they want and all of the fields that they want. Because we know those fields behind the scenes, we're actually adding the field parameters to the outgoing JSON API responses so that it's by default using a sparse field set. So behind the scenes, it's also cutting down the size of the payload. So my hope here is that even though having this translation layer in the middle has a cost, being able to kind of automate getting a small payload maybe balances that out. But, you know, we can also measure that too. Everybody, how's everybody doing so good? Still rocking our Thursday? All right, awesome. Okay, so now going all the way back to where we started with the generic Drupal web components project. So obviously huge, we took a huge tangent and focused on Drupal state to hopefully make it possible to build more Drupal friendly web components. And now we find ourselves that, you know, if, you know, state management and some of these ways to get data from JSON API are solved, the hope is that projects like this and others can focus on the stuff that's going to make their, you know, decoupled project unique. So this is a couple of components that were created in that generic Drupal web components library that uses Drupal state. And in a previous version of this talk, I had kind of an initial approach to this. But Andy Bloom from Lollabot provided some feedback and some examples and refactored the approach here to something that I think works even better, which we'll take a look at in a second, but definitely hat tip to him. And also, if you want to mess around with web components, definitely would be interested in others who want to contribute to this library. But anyway, so we're importing, in this case, all of the components from generic Drupal web components. Again, the magic here is happening in the markup. So we have a couple more custom elements. So the top level is the GDWC store. So that's, you know, essentially the instance of Drupal state that we saw before passing in similar parameters. And that gives you a data store and that the state management, you know, at that element. And then inside of a store, there can be one or more providers like we see here, there's just one provider. And you can think of that as essentially the, you know, the get object requests that we saw before. So a provider can try to get an object from Drupal's JSON API. What it does is it talks to the store and it makes its request to JSON API stores that in the local data store. And then we'll start playing around with this in a second. But the inside of a provider, you can have a template. This is actually the HTML template element that are used for custom elements. And that template has its scope is the provider that it's inside of. So it has access to essentially all of the data that the provider gets back. So in this particular example, we're saying that we want one particular recipe with this ID. And we're also including some image reference here. But so now we have access to that recipe. So I can just write regular HTML marker here if I want to. And then double braces is the format that I used here. But if we just say title, we have our deep Mediterranean quiche in this case. So this can be just any regular good old fashioned HTML. What's in this template could also be web components. So it could be web components from this generic Drupal web components library. But it also could be any other web component with this approach. The previous version of this required there to be some logic inside of the generic Drupal web components components to hook into this. But by using this template and essentially making these variables available to the template, just literally any elements can be used here. So for example, phase two this week unveiled, I think it's outline, which is a web components library. I tried to chat with one of the phase two folks yesterday about this. But that library could be used with these two components to get data from JSON API and then do all sorts of fun things with that really cool web component library there building. But let's look at an example, a little copy and paste for presentation sanity here. But if we wanted to use, we did create a kind of an initial pass at a card component. So if I wanted to use the card here in the templates here, we have our image in the card. The summary is being provided here. There's also another prop that we can pass in for I believe the headline. So if we make the headline, the title, the headline. So now we have our card, our image, our deep Mediterranean quiche. Another thing that the the provider does. So if you just get one item back, it will render the template. But if the scope has an array of results, it'll iterate over the template. So if I take away the idea here, so I get multiple recipes back, we'll see that I have, you know, eight or so recipes that it spits out. And then, you know, again, because this is just, you know, the HTML template element, I can even do things like if I want this to be in a grid, you know, I can create a style element, you know, this probably isn't the way you would actually want to maintain your CSS, but I can reference the host element. So the host is essentially the container of the custom element. And then hunched over my keyboard here, I can display grid, GERD. My living nightmare is typing in front of people. Okay, display grid, and then I'll make it maybe a two by two grid. GERD. Perfect. Grid template. Oh, God. I think part of the problem is that I can't talk. My son like plays video games and like streams on YouTube and like he can't not talk while he plays video games. I just, I don't get it. One FR, one FR. And I can't not have the gap here. So I'll put that in. Cool. So yeah, now a grid of recipes. And yeah, that just seems really flexible. And like this was the, you know, what I was hoping that this library could have as far as being able to have a solution for managing state from Drupal that can be easily shared. But this approach, I think, you know, goes even beyond this library. You know, I could see people using just these two elements with, you know, stuff unrelated to the components that are provided in generic Drupal web components. So pretty excited about it. All right. So a few things as we kind of come back from our journey. So given all of this, given the like a year or so tangent that, you know, led to this library and those components that we just looked at, where could we go from here? What could we do next? So I performed a very unscientific survey as a way to answer that, which is searching on NPM, which is the thing that I think, you know, JavaScript developers do do. So if you search for Drupal on NPM, this is the result that you get back. The first thing is an implementation of parts of Drupal's user access control API. And then a JavaScript implementation of the hashing algorithm used in Drupal. And then they're eventually down at the bottom is Drupal SDK. But, you know, is that Drupal's SDK? There are other ones that are in the results. Like it's for somebody just searching Drupal on NPM, this is, you know, probably not clear where to go from here. If you are, if you know to look under an NPM organization, there is a Drupal organization. Right now there are just two pretty specific packages, an implementation of a replacement for jQuery once and accessible autocomplete. These are things that are, I believe actually used in core, at least that's the intent. But, you know, there is the opportunity here and some of the work that the decoupled menus initiative and the creation of general projects in contrib opens the door to having more things under the Drupal namespace here. Alternatively, like let's look at searching WordPress. Searching WordPress gives you a more sane set of results from my opinion. The first result is a client for working with WordPress. And then there are a number of libraries under the WordPress org. I think a lot of that is driven by the block editor because that's in React. So I assume these are also a lot of things that are actually used inside of WordPress. But, you know, this definitely looks like a kind of more consistent set of WordPress related JavaScript projects. And then Sitecore. So Sitecore also has a set of APIs and essentially like an SDK. So if you search for Sitecore, there also are a number of libraries, you know, specifically for interacting with Sitecore in a JavaScript application. And then if you search for Contentful, I know that this is not necessarily a one-to-one example because Contentful is a exclusively headless CMS. But obviously, there are utilities to help you get data from Contentful in the JavaScript application that you're building. And imagine a developer who is familiar with this and maybe is moving on to a project where they're going to have to talk to Drupal. You know, the first thing they might do is search for Drupal on NPM and expect to see a set of utilities like this. And today that doesn't exist. So what could we do to make that better? As I mentioned before, there could be more tools under the Drupal namespace or something like it. You know, another thing that has been suggested as an idea at my commercial at a previous version of this talk said, you know, maybe there could be like a Drupal contrib namespace under NPM or something like that. But yeah, something more kind of clearly collected as Drupal projects on NPM. I do think that there should be a some sort of official Drupal JavaScript client, as you can probably tell. And, you know, obviously I've been working on a library that solves some of those problems. But I think the more important thing from my perspective is that there is something that fills that need. And then also, this is kind of an offshoot from the decoupled menus initiative. But there really isn't much documentation on decoupled Drupal on Drupal.org. And I think having some documentation and kind of some clearer examples and best practices there would also help quite a bit. So, you know, what could the actual next steps be? You know, we're all here collaborating and working together. One thing could be promoting projects, existing projects to the Drupal namespace that could be, you know, I think that could be useful, but also a good exercise to try to determine like, what are the rules around that? What is appropriate for that namespace? What isn't the Drupal JSON API params? It's something that this library depends on. I believe Drux has it as a dependency. It's a great utility. It's adopted by the community. That could be a place to start. I've actually had it on my list to try to open an issue to propose doing that. And I do think, I do believe that there should be efforts to actually, you know, work on and build and create some sort of official client or SDK for Drupal, a JavaScript client to interact with Drupal. So this week, I created an issue in the Ideas queue. There's the link. I've also tweeted out previously in the week. So I would love anybody's feedback on that to hear thoughts, even if it is just to pop in and say like, hey, I think this is a good idea or hey, I went to Brian's talk. I think it's a terrible idea. Either one of those would be useful too. And then additionally, as part of the decoupled menus initiative, there was initial outlining and a lot of thoughts around what would a guide to decoupled Drupal be. And we're trying to focus on declaring the menus part of the decoupled menus initiative complete. So we kind of broke the scope of that out. But I think there could be the opportunity for a more organized effort around trying to actually create some decoupled Drupal documentation. There is a section that was created under the developer guide on Drupal.org that is a home for that and essentially has the outline. So the home is there and we could start furnishing it if there are people who are interested in that. And yeah, I mean, this is the last day of DrupalCon. So, you know, a lot of the contribution has happened, but I'll be for as much of the day as possible in the contrib space. There's a bunch of issues in the Drupal state issue queue. There's that ideas queue issue that I mentioned for the decoupled menus initiative. The things that we're trying to get across the finish line this week is there's a core issue for the endpoint, getting the endpoint into core. We're really close. I've had some great help this week. I see Gabe here. Thanks for your help yesterday. We just need to wrap up some tests for that. So if there's anybody who's better at tests than me, come find me. And we have essentially documentation page that's specific to decoupled menus. There's just some revisions we're hoping to make there. Wrap that up. And then there also is that generic Drupal web components library. And I think that can definitely be a space for people to just create new web components. So if you're interested in doing that, let's talk. And if you're interested in anything else in this space or just want to chat about this stuff, I would love to talk more. And I think we do have some time for questions with this very aggressive discussion slide. So thank you. Yes. Love to be here. And again, you're all the true heroes Thursday morning, but questions, Benji. And I will try to remember to repeat the question because I know you would tell me to do that. I wouldn't be doing my job if I wasn't making Benji nervous in some way. That is totally valid. What I think that... Oh, yeah. Oh my God. So Benji's question was fighting out the response, deserializing it. Isn't there a risk of conflicts for similarly named things? That is definitely true. What I would like to see the library do is have that as an option. So if you didn't want that to be deserialized, you could not have that done. I do think the value in doing that is outweighs the risk, but that is a valid concern. Yes. The question was, does the library help with posting data back to the server? It does not now, but that seems like a really natural thing for it to expand out to doing, or whatever ends up being Drupal's SDK. Any other questions? Yes. Does pagination work? So JSON API, by default, will only give you a certain number of results. It might be 50? 50. And then beyond that, it pages, which is great. It's great that it has pagination, but a lot of times people just want to get all results. The library does handle that. There is a get all option, so you can pass that in, and it'll get all results, and behind the scenes, it goes through all the pages. And that's another example of something that a lot of people do. It's code that people are writing over and over, and I think it's useful that there's utilities that just take care of that. Other questions? Yes. So the question was, the question slash statement was that being able to provide a GraphQL query with this library seems really powerful. Was all that you needed to do to do that to provide the query in the get object request? And yes. That was a nice succinct. Yes. Okay. That is a good question that I need to clarify then. So, and I can totally understand how you would jump to this conclusion, because again, it seems like this shouldn't be possible. But what the library does now is it allows you to write those GraphQL queries against Drupal's JSON API. So the GraphQL module in that example is actually not installed and enabled. It's essentially a way to have the convenience of writing a GraphQL like query against JSON API. However, I do think that this library or especially, you know, Drupal's official client should also have some sort of pre-packaged library to interact with the GraphQL module. So, and Drupal state uses Apollo client, at least for the, that GraphQL link thing. So it would be pretty easy to provide, you know, a client instance that could talk to GraphQL. But that, yeah, that hasn't, the work there hasn't been done yet. Any other questions? Yes. So the question was they like the fact that the data gets cached, but they wonder about case where the data is stale. Another thing that I've run into is the legitimate example, like, let's say that you make your initial request for just certain fields and later you want other fields. Does the library handle that? It does not right now. I think that's a big area for improvement. There are issues in the issue queue about it. It's, you know, it's a bit of a rabbit hole. It's a pretty challenging problem, but I think something that this library or a library like it would need to solve. So if anybody, anyone wants to lend a hand? Any other questions? Yes, Gabe. The first time you land on a page, how does it decide what to fetch? I don't follow, actually. So you in the, to get the data, the way that you call the library, you're essentially telling it. So you would have to say get object. And if you wanted a page in that case, you would say get object and provide the ID or you could use a couple of router to determine what page is related to that route. But basically it knows because you tell it. Yes. Yeah. So to try to summarize that. So right now the web component example that essentially uses Drupal state requires some sort of component hierarchy. And the question essentially is, could there be multiple stores that share a store? Or, you know, yeah. So the answer to that is, is actually it does that now. So you could have one store and then multiple providers inside it. Any, any child provider in it accesses the same store. Another kind of question that I've heard about this approach is, you know, yeah, does it have to have that rigid component structure? There, there could be ways to have that be part of the global namespace so that it's possible to access that. My general understanding is like from a JavaScript perspective, that's kind of an anti pattern. So I don't know, something that could be considered. But again, that's another thing like I also consider this very early. So any feedback, any ways that we might be able to make that more useful totally open to it. Thank you. Any other questions? Great questions. All right, everybody's up, but thank you so much. This was great. And I'm proud of you all.