
An interactive look at the unique features of Brightspot’s GraphQL implementation as well as the API Framework on which it was built by Brightspot Chief Architect Dan Slaughter.
Speaker 1: Good morning everyone Welcome to an in depth look at bright spots, graph QL Speaker 2: api my name Speaker 1: is dan slaughter. I am a chief architect here at bright spot and I'm going to be walking you through a host of features that we have built over the last two or so years uh, that have made the graph QL plug in what it is today. We have a lot to cover and so I'm going to go ahead and get started and before we dive into actual graph QL there is something called the A. P I framework that we built before the graph QL A P I. And the goal there was to address a number of sort of common ap I call it boilerplate problems that any ap I would have to solve for and we could use that as a foundation for building the graph to L A P I. But also to allow bright spot developers to build any A. P. I that they want. So this aPI framework, we're gonna spend a little bit of time in the beginning covering those features and those of you familiar with graph QL um, we'll start to see some of those features that maybe you thought was just the graph QL Api but it's actually the aPI framework uh doing its work and after that we'll actually dive into the core features of graph QL and then dive into some of the differences between the content management A P I and the content delivery api namely you know, describing what they are there differences and and their unique features. So with that let me start on the A. P. I frank. Excuse me. Um so as we go through this this format is going to be a little bit different than some of the demos that you'll see later today where this is just gonna be a lot of little micro demos that showcase the various features. And so this is kind of the format we're gonna follow where I'll show a use case, I'll show a quick demo and then talk about you know, kind of where we plan to go from there and then we'll repeat that process throughout the call. So the aPI framework, we identified a number of different use cases that we thought any ap I would need to address to be something that is production ready, things like you are l management, being able to deal with security permission ng error handling. Um We thought extensible. Itty was super important if you've done any work on bright spot, you know, we love to have extension points and so there's no um difference there. And then finally uh analytics. So with that I'm actually gonna start and we're going to show a lot of code examples today. Um and even if you're not super familiar with java, you should still be able to follow along and I'll highlight the relevant parts that you need to understand as we go through this. So with that we'll actually start with our hello world of the A. P. I. Framework. Um so here we go in my uh intelligent I. D. Here I have my very first api endpoint and what you have to do to take advantage of this system is simply extend this class. The most notable thing about this class is that it extends record, which means like everything in bright spot, it is content. Um so you build your articles and your galleries and everything else, you're gonna do the same thing with your A P. I. S. And so hopefully a lot of this will be familiar to you as part of that. You will need to um override a few methods. So you can see I have a path here and then a method called serve which takes a request and response and if you're familiar with building, you know http surveillance in java, this is very similar but this is sort of a blank slate. It's up to me to kind of do all of the things I need to do to um return my response. So by doing this extending this class, you've now essentially notified bright spot of it. And inside of the CMS in the api section of the administration area, you can now see you're a P. I. And so this is my very first one api demo and you can see the path that it's associated and if I go to my front end here, I have my status of okay, so my A P. I. Is up and running, it's live and this may not seem very impressive at this point, but there is one very important thing that you're getting for free is that by um doing this, you've essentially opted in to bright spots directory system. So if a, you know, an editor or someone were to come along and try to publish content at that exact same U R. L. They're gonna be met with an error that says, sorry, this is actually already taken. Um this may seem trivial, but if you've built an HDTV servility, you define the U R L is completely separate, you know, in your web dot xml or somewhere else and you could actually end up with conflicts and it will result in someone, I'm not sure who, whether it's the editor and the developer being very confused as to why um you know, they're seeing something that they're not expect. Um and thinking about a P I. S, we sort of acknowledge that Jason is the most common um kind of format. And so we wanted to provide something that made building Jason based a P I S a little bit easier. And so in this next example it's going to look very similar to the first, except I'm extending Jason api endpoint um and rather than a serve method that is void. I'm here returning essentially a map that says, here's the data that I'm going to return and notice here. I'm also returning this value message. So remember this is just a content type like anything else. Also note that I've implemented Singleton to say hey there's only one instance of my api endpoint and that's why when I come over to the aPI section and go to my demo to it's automatically there and then I have a message for your field and I can save it and if I go to my front end now and hit a P. I to sure enough I get my response with my message. The next thing that we wanted to tackle was off. Um you know obviously we wanted to be able to protect our A. P. I. S and I encourage you to do that protection outside of the application but we also wanted to provide in application support as well. So again following on the previous example it's going to look very very similar. The only difference now is I've added a little bit of code that essentially says, hey I want to pull a client I. D. And a secret from the request header and me as the developer. I actually get to decide where I'm pulling it from. So I'm choosing to pull that information from a header. It could be a parameter, you could pull it from a cookie, you could name these something else. It doesn't really matter. But this line of code is essentially me declaring here's how I want the credentials to be passed into my A P. I. And then when I call this line here resolved client. Um The api framework will kind of work its magic and verify that the correct credentials were passed in. So if I come here and go to this api endpoint actually get an error that says the credentials are invalid. Um If I go to this endpoint you'll See that there's two clients configured on it client to and client three and in the same screen I can actually manage all the clients and what endpoints they have access to. And then you can see I have my client I. D. And here's my secret key. And so if I go back to my endpoint now and I'm gonna use a little browser extension trick um to basically pass these headers when I refresh says the client is not authorized. So let's try someone else who maybe does and there we go. Um Now this client has access to this api um So once you've identified who the person is you may want to further say, okay well I know who you are but do you actually have access to the resources um that this api is providing And so this is where sites and permissions come into play. So again I'm gonna show another example looked very very similar to the first um The only thing I'm doing extra now is essentially saying hey I want information about a particular site and in this case I'm requesting a site U. R. L. Could be the site idea. It could be the name you as the developer can decide how the site information is passed into the system. And again I'm basically saying okay once I have that information I'm going to make sure that the client and the site they're requesting all checks out and then I can perform any site specific business logic after that. So if I go into my config now And I'm actually gonna show api client three and you'll see that in the permissions field I've given them access to demo site three. Um And if I go to the front end now for this user and I'm gonna put in an incorrect site you're all for the moment. So this is demo too And it says insufficient client permissions and that's because this particular user only has access to site three. And when I come in and change my request header to say Demo three. And as you would expect access to the to the content of the A. P. I. Is now available. The permission ng system, it is one of the areas many areas that is extensible. So you can actually define your own custom permissions. The one you just saw with site is built into the system. Um but you can also define your own. And so I have an example here on demo client too where in this drop down you can see there's an I. P. Allow list. So how did I do that? Well you can create a class that extends api permission and in this case much like the endpoint it's also a record so all of the bright spot data modeling goodness you get. And in this case I said hey um I'm going to define a set of I. P. Addresses that can be entered and then I have to implement a has permission method to say hey does the requesters I. P. Address exist inside the set of allowed I. Ps. And so if I do that now and I say oh I'm going to only allow requests from you know this address and I'll save this on this client. And if I switch to that client On AP. i. five I get an error that says forbidden. And then it kind of gives me some information around oh we expected it to be this address but actually we got this one instead. Um Again me as the developer I'm controlling all aspects of this and what information is returned in this response but for demo purposes I'm kind of out putting all of the relevant information. So clearly this api is expecting this I. P. And uh so I can actually go and tweak my headers here and I'm gonna pass in a header that will sign of act as my I. P. Address which matches the one that's expected and if I refresh then sure enough I get a status of okay and access to the api is granted. So um you know, you can go and kind of come up dream up all sorts of different permissions that can be applied to the clients who are accessing your endpoints. The next bit is multiple endpoint configuration. So up to this point, every endpoint that you've seen Has implemented this Singleton interface, meaning there's only one. Um but you don't have to do that. So in this example DEMO six here, I'm extending Jason, api endpoint but not singleton. So I'm going to be able to create multiple of these things and um now I actually need to be concerned with well what path does this endpoint live at And I just chose some contrived logic here that says, oh we're gonna hit a PI six and then you can enter in your own kind of suffix that will go at the end of that. And so again with, you know, data modeling here with the name and a path suffix. If I go in here, I now in the create dialogue C api demo six as one of the options. So I can come in here and create a new A P I passing the name passing a path and save. And so I have a few examples already created. So here's version A and then you can see the path is a P I six slash a mm hmm. And so now I'm hitting this endpoint and then if I go to be I'm hitting a different endpoint. Um and it's it's it's that simple and obviously we took advantage of this uh for graph QL which is why you see those options in the drop down there. Okay. Next is uh surveillance. So some of you may be hearing about the api framework for the first time and um and you may already have some api code that you've already written and thinking well, okay, this is kind of cool. How do I take advantage of this? Well, one option is to just rewrite everything but we thought that we could at least help that process along a little easier um with a new concept which is a serverless api endpoint. And so in this next example I have an existing surveillance, I have overridden the do get method and done my typical java thing. And so this is my existing code but then I can come in and create an api endpoint that extends serverless api endpoint and basically reference my servant in the square brackets at this point, all of the same facilities to me that were available. And the other examples are here. Now I've given it a path um bright spots directory system does support wild cards. So um, you know, you can do that as well. And so if I come here to my Example, seven uh slash food Barbas whatever. Um and there you go. So this response is actually coming from my serve. Let's do get method. Okay and finally uh and probably the most powerful of them is request to intercept. So this falls into the category of extensive bility again. And so you've seen these examples and while we have removed a lot of boilerplate uh and making you know doing the whole client authentication pretty seamless. There is still boilerplate in the code. So for example um you know having to do the client authentication every time and say oh I need to look for these headers. Um that is in essence boilerplate. And so in this last example I have something called an api request listener and this is very similar to what you saw earlier but this time I'm saying actually I'm going to look for a query parameter for the client I. D. And the secret. And so this is going to apply to all of my api endpoints and the api request this in their interface has a number of different callbacks things like before process on success on error after process. And so you can hook into these things into the life cycle of the api requests and do different things. And so in this um final endpoint example here you'll see that I'm not actually doing that boilerplate code anymore. All I'm saying is resolve the client that's it and then I'm going to print out some information. So if I go back to this A. P. I. And now I'm actually gonna pass the client I. D. In secret in the U. R. L. And success if I remove it, I get blocked. Um But that's just one use case for the intercept the other use case. Um You can do things like logging. So here I have an example where at all of the different life cycle uh steps, I'm just going to print something out to my console and I have this set up so that it only turns on when a log parameter is present. So if I come back to my U. R. L. And say and log equals true and I'm gonna kind of spam the refresh button a little bit and you can see all the output in my logs now and you can see that this is coming from uh this this particular endpoint. Um So this is very powerful because you can write these things and kind of influence if you need to do any type of auditing. Um And if you're paying attention here, one of the other use cases is actually for analytics. So this particular endpoint is actually printing out information on the number of requests um to this endpoint and the number of requests that the particular client has made overall. Uh And so you don't have to do anything special to get access to this information. Um It's automatically collected and in this case all I'm doing is just getting the data and printing it to the response. Uh And so if I actually go back to my other a p i s like api demo one, there's an analytics tab and you can see that this was lacks access uh you know at 11:20 there were 44 requests and you can see even a breakdown by client that this client access it seven times and this one accessed twice. So that is the api framework in a nutshell. Um as far as where we plan to take it, it's really just a matter of providing more based implementations, more, you know, types of permissions out of the box, more authentication options, different output formats like the Jason api endpoint and then we'll also um do some things with key management. So right now the keys are kind of created in the editorial ui but for the security conscious they, you know, you may want to do things like key rotation and we want to kind of help you along and make that those types of use cases easier for you to do. All right, okay. Um as far as how to get it as a bright spot 4.2, it's part of the core CMS. So you pretty much can just start using it. There's nothing extra to include um and now we'll actually take a look at how we leveraged all of these things to build the graph QL endpoint. So some of the core features of graph QL I mentioned that there's these two different types of endpoints but every graph QL endpoint um is able to take advantage of the graphical Explorer in the CMS, um you know, managing aPI keys, core's configuration, the persistent query protocol and then things related to schema, documentation and versioning. So the first thing is the Explorer and for those of you who have used um the A P I you're no stranger to this and the developer tools, you can go to grad school Explorer and you can see all of your graph QL endpoints. Um turn that off. And you know, this Explorer is using something called graphical and we're essentially just embedding it into the CMS. So this is going to allow you to easily kind of construct your graph QL queries, you can explore documentation. Um you can actually view the, the actual schema that graph QL generated, et cetera as far as this tool. You know, we're going to keep up with any changes that are made to the underlying library, graphical. But the one thing that we are going to add that it does not have today is a dark mode. So in general it has kind of a different looking feel of the CMS. And so we're going to slowly try and, you know, make it look more and more like the CMS, including support for dark mode. Oops, so the graph QL obviously there's an aspect of aPI keys but there's other kind of things related to graph QL that you have to deal with. Especially if you're building an app, you have to deal with cores and then you may also want to protect your endpoint from kind of unwanted exploration if you will. So we're gonna go to example here. So in this example I have a view model that's going to be used to kind of power my graph QL A P I and it's going to be pulling information the title and description from actually a header. It's very contrived example. Um and oh you know what, I did not show what a graphical endpoint looked like. So um you can create graphical endpoints editorially and many of you have but we shouldn't forget that you can also create them in java code. And so it looks very similar to the examples you saw earlier but this time I'm extending content delivery endpoint. Um it's implementing singleton. I still have my path and then I'm basically telling it, hey, here's the view model or data model that I want you to use to generate the schema. And so in this example here graphical demo too, I have a number of different settings that I've added to it. I said api key is required. I'm not doing anything with cores and I've blocked introspection Cleary's now when I go into the graph QL Explorer and go to this, there are no problems I can query and get back data and everything is good but if I were to use something like um this tool so this is just a tool out on the web. Um That is actually a graph QL Explorer and you'll notice that it says no schema available and if I open up my inspector here, what's it complaining about? Well of course and so on my api endpoint I can actually set some configuration to say oh you know what I'm going to allow this origin and um I'm leveraging these headers so X foo and so I'm going to also allow X foo header to get past. I'll save and now when we refresh well I get a different error now it says oh 401 you're not authorized. Um So I could pass in my client I. D. In secret but for now I'm just gonna say nope, this api is public to anyone. And so if I save it refresh the errors, go away. But wait I still can't see anything in the schema Explorer. And so there's one last thing you can do which is actually block introspection queries. So this kind of prevents people from using one of these tools and just finding out all the different things that are available uh in your api so if I toggle that on it's safe and refresh and now I can happily you know explore the schema we are going to do some more things like introducing query complexity restrictions so that you know you can only go a certain level deep um and things like rate limiting and also analytics that go down to the granular level of which query and mutations people are accessing. Mhm. The next thing I want to cover is the persisted query protocol. So if you haven't heard of this it's actually something that was dreamed up by the Apollo foundation. So you can actually read about it here and they've they've got a kind of detailed diagram of the protocol but the gist of it is improved network performance by sending smaller requests. Um And so it's it's part smaller requests but also graph QL request by default our posts. And that's not great when you're trying to do any type of cashing with a C. D. M. So the other thing that persisted queries offer is being able to convert a graph QL post request into a get request. So I have actually built a little sample um request excuse me react app. And in the network tab as I start to fetch data and I'll just kind of keep doing this here. You can see post post post post post post post. Um So I'm not really getting a lot by by way of cashing. And so if I come over to my api endpoint and say nope I'm going to support persistent queries and I save now when I interact with this um you'll now see get get get get get get get now. This is a U R L. That can be easily cashed by uh C D s. One of the things we want to do with persistent queries in the future is something we are calling. The rest ification of graph QL So what I just showed was automatic persistent queries. This is great because it can essentially take any query and you send it as a post first and then the follow up subsequent requests can be a get. But there are scenarios where, you know, ahead of time, every single um graph QL query that you're going to make minus the parameters that you pass in. Um And so for that you can actually take advantage of static persisted queries which is basically saying, hey, bright spot here is the list of queries that I want to run and um and you don't ever have to make a post request even on the first one, it can always be a get. And so this idea for rectification is to essentially um move away from what is otherwise a kind of messi request format. Um So if I come here and show yes, so for those of you familiar with it, this is what a get request kind of looks like with the persistent query protocol and um it's kind of ugly. And so this idea for rectification is to basically prettify it and make it so that you have a standard set of endpoints that you can hit and you may not even have to know that it's graph QL at all because at that point you're just making a get request, you're hitting an endpoint and you're passing a parameter and you're getting a response. So we're we'll stay tuned for that. We're we're kind of excited about exploring that possibility. The next example has to do with documentation. This probably is my favorite example uh here. So I'm gonna bring up another demo but I have a view model and I decided to be a responsible developer and actually write documentation. So I have java docks here. If you do this inside of your code bright spot. Well read that information. And so when you see things like alpha, bravo, charlie, delta and you open the documentation Explorer, I'll blow this up a little bit. You can actually see what all of those things do and that's great. Um one of the neat things about the graph QL specification though is that it actually supports markdown. So if you're really inclined and you're an overachiever, you can um really go to town with documentation. So here's an example where I have All sorts of HTML H 1's H two's images, code blocks lists and what we do is we essentially convert this html into markdown. And so if I look at this Foxtrot field and there you go that documentation is coming from the java docks in my view model code and and you can take it one step further if you are building a react application. So here's my little sample react application and you decide to leverage typescript, which I highly recommend and things like the graph QL code generator. When you couple all of these things together, a front end developer can start consuming you're a P I. And right from within their I. D. They can see the java docks uh that are part of your schema. And so if I click on demo for relation there it is. And then the last thing is schema versioning. So in this example I have a view model with a number of different fields, title description, short description, day, month year et cetera. That's great. I can, you know, boot it up into my graphical explorer and see the different um fields etcetera. But what happens when someone comes along and says, you know, I don't want this anymore and I'm going to deprecate this and this should actually be a string And this needs to be renamed and I'm going to add two new methods. Well, if you were depending on that end point having a certain structure, uh these changes in essence just broke it. Well there's two things to say about that one. Well don't do this, you know, you should deprecate things in favor of just flat out deleting them. But also when you do it and you go to your endpoint configuration, there's an advanced tab here that there's an advanced tab here. One sec refresh that keeps track of all the different schemas that got loaded and so I can actually click here and see what the new schema looks like. But more importantly I have this compare button, so now I can actually see a side by side diff of what changes were made to the schema. Um The new type was added in in various different changes, ideally you'd like to see a schema where the only changes deprecation is and you slowly face things out, but this is gonna catch uh you know, a lot of, you know, potentially breaking changes that are made to the schemas. All right. Um Yeah, so as far as where we want to take the the versioning thing, the only thing left to do there is really just having a tighter integration with the software developer or not so much the software development lifecycle, but the your any ci cd pipeline that you have in place so that when a developer does do what I just did um that gets caught in the build cycle, um so that we don't end up breaking things for our consumers, graph QL in it of itself already makes it harder to break things uh this is just kind of an extra kind of layer that we put on top. Okay, so moving on to those are the common features and now I want to kind of take a deeper dive into the two primary endpoints that we provide uh with our graph QL plug in which is the CMA and the C. D. A. Uh And this chart kind of says it all the management API is geared toward systems to manage content whereas the delivery is geared towards delivering to end users. Um I like to think of this graph, you know, in terms of which we should use. The lines are a little blurry. Um There are use cases where you know, both the CMA and the C. D. A. Could solve um your problem. Um So figuring out which one to use, I like to use this as kind of a guide of um you know, which boxes do I check more of? Um So the management ap I always requires an api key. Whereas the delivery ap I can actually be open. The management A. P. I. Is backed by the dari record and query api So your data models. The management A. P. I. Is a way to query those things. Save those things and delete those things. Whereas the delivery A. P. I. Is backed by view models which for those of you familiar with the view system, it's like a transformation layer on top that lets you do whatever business logic inherently. The management Api makes use of mutations because you're saving things and deleting things. Um And while it's possible with the delivery api it tends to be less common. And then if you think about the management Api because you're working with dari records, you are dealing with the raw kind of unmodified data and so you kind of have to know what you're doing. Whereas the delivery api has a chance to have had logic applied to it cleaned up and you know, kind of easier to consume and digest. And if I had to kind of classify them, I would say the management API tends to be better for like migrations and ingestions. Whereas the delivery A P I is what you want to use to power all your beautiful web apps. Um I'm gonna talk only a little bit about the management api because quite frankly, um if you're familiar with the dari persistence ap eyes, you're already halfway to being an expert in the content management api So there's not a ton to say there, but I am going to show it uh just for posterity. So I'm gonna open up a Management api here, Demo six mm hmm. Try and blow that up a little bit. So here I can run queries and I can pass in offset limit, I can sort by various things and I can do wear predicates etcetera. So hopefully this is very familiar to you. I can get page info around how many things are returned and then actually get access to the data. So if I run this, you Can see I get 12 results back. Um And you know, I could say 00 well actually I want to filter and say where first name equals and then I'll pass in an argument of dan, I run that now I only get one result back. Uh In addition to that you can also do uh save and delete. So these are the mutations um delete you just specify the I. D. You can choose to whether it's permanent or not. Um And then save kind of follows a similar pattern where you have basically some inputs where you can specify the data you want to put in and it will save. Um One of the kind of neat things about this is I'll just do it real quick. Uh So first name will do todd last name Loiselle will return the I. D. And the full name title the box. So I ran that and I actually did just save something into the system, you can actually see this new employee Todd Loisel and it's published and oh I actually forgot to do it. My mistake. Well we'll have to skip it for now but what I wanted out was that as part of the A. P. I. You can pass in um the user that you want a tribute to it. So in this case I left it blank as it was published but you can actually specify like a system user that you want to attribute. So when stuff starts flowing in the system, you'll know who it came from and then the last thing on the C. M. A. I wanted to call out is that we do support an unofficial multipart spec so you can read more about it here. Um but basically what it allows you to do is to send binary data to the A. P. I. So rather than having to like send your binary data off to some other system, get back the metadata and the U. R. L. And then call the graph QL api you can do it all in one fell swoop. So I actually have a little again sample react app here and I'm gonna choose a file and I can see the graph QL response come back and inside my bright spot. Now sure enough there's the image just like that. Okay. Um so with the last amount of time I want to talk about the content delivery api it's probably what most people are using and I think it also has the most set of kind of rich features within it. Some of the things I'm going to cover is well, one the content delivery A. P. I is in the business of letting you build exactly the graph QL schema that you want, all the inputs, all the outputs you get to control it um and using your view models to do so um we also deal with things like rich text segmentation, images, there's all these things related to front end um that the content delivery ap I will help make it easier for you so go and just look at a quick example. So here I have an example delivery A. P. I. And the code that's powering it is some view models but the view system has something called, excuse me has annotations that you can mark on your methods and your classes. So here I've annotated It with Demo nine and some weird funky looking, you know, different keys and the graph QL ap I will honor that uh and reflect it. The other thing that you can do is add variables to your view models and annotate them with web parameter and the result of that is now inputs into your A. P. I. And so when you combine these two things, you can basically honestly you could use view models to replicate the content management api if you wanted to. Um And what's nice about this is that these annotations are not actually specific to graph QL at all. They're specific to the View system and the graph, you'll plug in just leverages them to um to kind of make your endpoint your own so rich text. I'm going to talk about very briefly, even mainly because it's a super complicated topic uh and we only have so much time but I have an example article here and it is full of awesome rich text elements that I've kind of programmed in here. If you're familiar with our R. T. It uses html as the sort of underlying data format to store these things, html and graph QL don't really mix. And that's because when you are defining a graph QL query, you essentially have to specify every single field that you want. But html can be an infinitely nested tree. So one solution is to just well send the html as a string. And you know, me personally would not prefer that because we have these rich uh you know, elements here that have fields that we want to be able to leverage in our graph you L A P I well, well the solution to this and actually it's been employed in a number of places. So I'll show you some examples um in the android community it's called span able IOS calls it attributed strings and we call it marked text which actually we got the name from Crows Mirror, which is our rich text editor. So it actually internally has this concept of marks and all the mark is is a way to flatten the html into something that doesn't nest, you know, regardless of how deep your um you know, your html goes. So if I open this up. Mhm. Look at my article actually, hold on, I have a query here saved for us. So um what I'm doing here is actually we can actually just explore the schema. That might actually be easier. So in the article body, it now has this thing called mark text and it's basically a plain text, string, plaintext and then a list of marks that have a start and end index and and then you can have different types of marks. So you can have a mark, that's a code block or a heading or an image or a link or what, you know or what have you. And so in the resulting response data you have this plain text and then you can actually see oh well the heading Starts at Index zero And ends at Index 27. And um so this is just a way to make it so that you can construct a graph QL query um that that is sort of finite and still pull all of the data. Um The one thing that we need to do ah is to provide and what we plan to do is provide a javascript library. So we'll probably put it in npm. That basically will allow you to take that resulting Jason. And you know, if you're using a react or whatever, be able to easily kind of iterate through all of the marks to render your components on the page. But you could certainly, you know, if it's a well defined kind of structure and you can certainly take advantage of it today. Uh segmentation. So the key takeaway with segmentation. Hopefully you're familiar with that feature just as a general bright spot feature. Is that as an ap I developer. So I'm building an api for my consumers and I have my data model here, title description and I have a view model that's essentially just spitting out the same exact data. And then I have an endpoint which really isn't doing anything special at all. It's just saying, okay, here's my here's my thing. So nothing about this code has anything segmentation related in it. However, if I come into the audiences area of bright spots and to find some audiences. So here I have an audience called business, an audience called developer. And um now I have some content that is filled out and I can actually switch and say, oh well now for the developer segment, I want to return this description but for the business segment I want to return this other uh ah message and if I go to the graph QL explorer, there's really nothing special going on here. I still just see the title and description and um you know, I can fetch the data. Now I have a little simple react after that is essentially passing in the headers that we saw in the Sorry about that I lost my where did it go? There we go. Um So this reactor is essentially passing in a header of either biz or dev based on the audience and when it does that, the graph QL ap I automatically responds with the correct data. And so the takeaway here is that you can leverage the segmentation features on the front end and the front end developer can coordinate with the segmentation plug in a bright spot but the A. P. I developer can sort of decouple themselves from that whole process. And lastly I'm just about out of time here. Um so the last thing I want to show is images and preview and theme fields. So in this final example I have a view model that has a title description and an image and I have an endpoint that is just like everything you've already seen up to this point. But I've also configured a theme. I have this demo theme here and I've defined a few different fields like primary colors, secondary color background color etcetera. And also as part of my theme I have some image sizes so I have my landscape, my portrait, my squares etcetera. And if I create some new content now. Bright Spot User Conference. Sorry, one more thing to show um I have a react app running at a local ports and in the settings of bright spot you can configure what we call content delivery. KPI preview. And so this is the U. R. L. To my react application. And if I open up the preview here sure enough my react app is spitting back the data and this is updating in real time. So as I type get updates. That's right. Um Now with the theme NG and image system we can start to make things interesting. So here I'm gonna come in and actually program some colors. Okay, And we'll make the font fantasy will save that and now when we come back we have a much kind of prettier thing and then I can go ahead and add my image that shows up and now with the image sized system, I can come in and uh I'm gonna increase the brightness and contrast here and I'll come to my large square and save that and I failed on my crop there, but now you can see the the, you know, this is all being powered by the content delivery API and so things like theme NG and front end fields and images can all kind of funnel through that system and produce a kind of whatever beautiful front ends you want and Mhm. Just in closing um You know, you, this is available in 4.2 but all of the latest stable features, um you'll want to be on bright spot four .5 for them and that is my time. Looks like there's two questions, can the aPI framework interact with a gIT hub repo um might have to ask for clarification on that, but I'm gonna go to the second one real quick, will there be support for graphical subscriptions? That's a great question. Um graph QL subscriptions are actually straightforward enough for us to implement in in terms of our application code, the challenge with subscriptions more so has to do with operational setup. So, um, you know, when you have a subscription, you're basically opening up a connection to the server that's sort of persistent. And so for something like the CMS, we do that for real time communication already, but when you're dealing with a front end website that might have millions of users on it at once, um you know, you need to make sure that that the operational setup of dealing with those connections is set up. So the answer is we could probably support subscriptions tomorrow from a java code perspective, but it's it's more about the operational setup. What happens if you don't know java or can't write java code in my environment. That's a great question. Um if you don't no job or can't write java and you want to build a graph QL a p i, you should go to the next sessions and stop listening to me because they're going to talk about how you can build editorial content types and also how you can build basically java classes using java script. And so all of the things that I showed here today, you could actually do with javascript. Um and and uh, you know, publishing within the the editorial tool. So, um that is my time. Thank you all very much for listening. And I hope you enjoy the rest of the sessions