To summarize: minimize.
It is impossible to use an SDK or API without making solutions depend on that SDK or API, including its JSON formats, .NET types, method calls, and otherwise. If you want a big .NET API, you are probably looking for an integrated experience platform rather than a CMS.
With headless, you use RESTful APIs to integrate. The SDKs wrap the APIs. The solution should make minimal use of both, and not just to reduce network and other computing resource consumption.
In some cases, the SDK may provide functionality that would appear to lower implementation costs. Other variables often more than offset this factor. Total cost includes learning curves for developers, cost and availability of developers with the required specialized skills in your region, dependencies on vendor upgrade schedules (when committed) including documentation and training, vendor lock-in, and probably many others.
Some vendor SDKs even show preferences for ancillary applications from the same vendor, which can lead customers to integrate suite technologies that may not match their requirements as well as alternatives from other vendors. RESTful APIs force vendors to expose equivalent functionality to all external systems, and work best when the vendor builds their UI and other layers on top of their own RESTful APIs.
You may understand my perspective if you think of the CMS as a generic data repository – a UI for managing relational, hierarchical, loosely structured, and/or fragmented JSON (where JSON can contain XML/XHTML, URLs of media, Klingon, maybe even Base64 for binary when you’re desperate, and anything else). So any CMS can support any data type using a simple text field. Focus on content modeling (including structuring of individual Entries and relationships between Entries) and usability in editing interfaces. Minimize use of vendor SDKs and APIs.
Here is some general advice.
- Avoid use of vendor SDKs that do not wrap RESTful services.
- Minimize use of vendor SDKs.
- Abstract all vendor SDKs.
- Look for vendors with infrequent SDK updates that are primarily about modeling (such as model generation tools), bugfixes, exposing additional features, and otherwise, not expanding the SDK or APIs.
- Centralize dependencies to the minimum number of projects that depend on on vendor SDKs using something like the repository pattern described in this blog. Your other projects can depend on these projects without depending directly on the vendor SDK.
Even for small SDKs that wrap well-defined and/or stable RESTful APIs, creating dependencies on a vendor’s SDK puts projects at risk. If you find a defect in the SDK, the vendor may not correct it immediately. The vendor may choose to stop supporting a version of the SDK, requiring you to upgrade all instances in all environments. Depending on the scope of the SDK changes, this can be a costly process, which is one of the drivers pushing customers to headless CMS.
Though all factors vary by implementation, consider maintaining multiple solutions that depend on multiple SDKs from multiple vendors with different release cycles for different products even within their own product lines on multiple instances (servers) in multiple tiers (development, test, UAT, production content management, and finally production content delivery), and if you are an implementation partner, for multiple customers, and all of this in multiple parallel universes. Minimize it. Wherever possible, move to SaaS, or at least REST.
The vendors typically suggest that you use the SDK as a NuGet package. At least during development, you may want to add the vendor SDK solution(s) to your projects and make your solutions depend on those projects rather than the NuGet package. In this case, avoid altering the SDK code unless absolutely required, in which case be sure to inform the vendor to implement a corresponding change. When possible, consider alternatives such as extension methods, especially for functionality that changes APIs or behavior rather than just adding instrumentation to the vendor’s code. To avoid complications, costs, and risks, you would not want your branch of the SDK to differ much from the code used by the vendor.
This presents certain challenges for .NET Core projects that use headless CMS, especially ASP.NET Core. Abstraction (repository) and dependency injection to the rescue. The vendors provide APIs to register dependencies, but you may want to wrap or implement those independently. In the project(s) that depend on vendor SDKs, I configure dependency injection for connection options (typically using what I think is a standard .NET pattern that supports appsettings.json with overrides from environment variables and elsewhere) and the CMS connection object. In web projects, I configure dependency injection for a repository singleton that basically wraps the connection and pass that to the controller constructors. I am not a DI expert, so I haven’t looked into how to do all of this without direct dependencies on vendor SDKs in the web projects. Maybe I just need to wrap their APIs. Maybe I can scope the connection service so that only the repository can access it. Maybe I need to use their logic to get the connection without using dependency injection. I wish I had more time, more eyes, more hands, and more skill as a developer.