Hi James,
I do not think that we should use Optimizely Graph for this case. You can consider to create new api to return mega menu model with sub-items. You can use IContentLoader to retrieve menu items automatically from decendants of start page. Of couse, we could define maximum level of mega menu to get only necessary items.
If you still want to use Optimezely Graph then I suggest that you can return more info in response such as parent link or ancestors and rendering mega menu level based on this data
Not sure I agree with this statement "I would construct a ViewModel with this information in the controller, however, we don't have that capability with Optimizely Graph.". Why can't you construct a view model in the frontend (or whereever you're making this graph call)?
"Do I include the page children in the request and delegate the filtering to the frontend?" Yes, include as much as you need in your query to graph.
Hi Johan, the context of that statement was from a backend point-of-view. I'm quite new to headless architecture so I'm trying to piece this together currently.
So what you're saying for this scenario, the correct practice would be to pass all of the data into the frontend and apply the filtering and business logic there?
I was just wondering if there was a way to intercept the queries in the backend to make them slightly more efficient, e.g. a custom resolver to intercept the request and add some further context to the response serving the frontend, to make the frontend logic a little less complex.
It would be much easier to write some C# backend code to include a node called "IsTopLevelItem" for example.
"So what you're saying for this scenario, the correct practice would be to pass all of the data into the frontend and apply the filtering and business logic there?" That's not what I'm saying. Still a bit unclear to me if you're actually have a headless setup or just making API calls from client-side? You can still have a backend even though you're running your application headless, it can be C#, Node.js or anything, but it's not hosted by the same application as the CMS then. This is often referred to as having a Backend For Frontend (BFF). Headless means that your application is not hosted by the CMS application. Are you still able to deploy code to the CMS application? If yes, then put logic there and expose it via Web API endpoints if you don't find Graph to cover what you need. Then you can use the built-in APIs and Graph.
We are striving for a headless setup yes, but if it's true that the rules of headless mean that the backend code should be seperate from CMS, then that's where things get a little complicated.
A backend is still needed for CMS when using Optimizely Graph for headless, because it's needed for defining the content models for pages and blocks.
Yes, we are able to deploy code to CMS - we're running a base CMS12 solution with the Optimizely Graph add-on, so we have the full capabilities of .net core.
It just doesn't feel right to go with a hybrid approach of creating a custom endpoint for this scenario, whilst also having other scenarios as GraphQL queries, as things will start to get messy.
(...and especially if it's true that Backend code should be seperate from CMS).
If you don't want to add code and endpoints in the CMS application, then create a separate backend (BFF) and host it together with the frontend. You'll most likely need it in the end anyway, e.g. for server-side renderinging or React Server Components.
Thanks Johan, having re-read your comments, I think that makes sense actually.
So in terms of the flow, it would be something like:
Frontend -> BFF -> GraphQL -> CMS
That would definitely clean things up for us.
"A backend is still needed for CMS when using Optimizely Graph for headless, because it's needed for defining the content models for pages and blocks." Not entirely true. You can model via the UI or API as well. Some things are however only possible via content models, as-of-now.
I think Johan has already done a great job to explain that.
As he mentioned, BFF will be needed at somepoint. From a good architecture perspective, you'd better to start with BFF as mandatory instead of create a bounch of silos api calls in the client app first to get job done for now.
Think about if you get charge in API calls, rate limit etc, it's not going to work by spreading api calls over the client app. Move to headless is a conceptual change. Instead of poking around how to build shaped data using CMS related SDK, you end up by composing APIs in BFF (can be via RESTful or Graphql). For business application developer, you don't even know what provides the data behind (it could be cms, elastic, nosql etc). The most common and easy way to start BFF is using cloud service like Azure Function / AWS lambda.
I am building a headless website in CMS12 and the new Optimizely Graph.
When building a traditional MVC website we had the power of C# and the powerful Episerver SDK at our disposal within the page controllers, so that we can apply business logic and filtering, before passing data to the frontend.
For example, let's say I want to fetch the website navigation with a simple GraphQL query, for rendering on the frontend
That all works fine, however, if I'm building a mega-menu in the frontend for example, I need to to know what pages are "top-level", and what pages sit underneath each item. In a traditional architecture I would construct a ViewModel with this information in the controller, however, we don't have that capability with Optimizely Graph.
So my question is, for this scenario, what is the best practice to tackle it?
- Do I include the page children in the request and delegate the filtering to the frontend?
- Or is there a way to add custom resolvers? I couldn't see it in the docs, but if not, are there plans for this, or any plans to give us more server-side control?
Thanks
The accepted answer here suggests following a different approach by using a BFF.