bridgetownrb / bridgetown

A next-generation progressive site generator & fullstack framework, powered by Ruby
https://www.bridgetownrb.com
MIT License
1.13k stars 114 forks source link

feat: Adapter-based Content API strategy to mitigate vendor lock-in #53

Closed jaredcwhite closed 4 years ago

jaredcwhite commented 4 years ago

One of my biggest concerns with starting to build integrations with headless CMS APIs (Sanity, Contentful, Dato, etc.) is the likelihood of vendor lock-in. It's one of several reasons I personally gravitate towards solutions that keep content in Git as much as possible (I make a conscious exception here with regard to images, as the DX of Cloudinary for image processing is second to none).

However, there's no denying the staying power and potential upsides of the API route. One potential way we could go here to take a page out of Rails' ActiveRecord adapter strategy. In Rails, you can choose among PostgreSQL, MySQL, or a number of other database engines, and the API you actually write to stays relatively the same. They've put a lot of work into providing that level of abstraction. Sure, you can drop down to SQL and write code that only runs on PG or whatever, but that's a last resort if the higher-level APIs don't work well.

I'd like to see the same thing in Bridgetown. Define a schema of some sort and expect data to flow in a certain format, and the question of whether that data is coming from Sanity or Contentful or whatever is more of a a business decision than a technical one. It also means if you need to switch APIs in the middle of a big dev cycle, the disruption would be minimized because the Bridgetown-layer code hardly changes.

I not sure yet if this is made easier or harder in the adoption of GraphQL over REST, so that's also something we need to investigate.

Comments? Feedback? Ideas?

KonnorRogers commented 4 years ago

This seems like something best left to a plugin. Similar to defining Adapters in a database.

Gatsby is what I'm most familiar with. To avoid that sense of "lock-in" they use plugins.

IE:

gatsby-source-netlify

gatsby-source-sanity

As for REST vs GRAPHQL it should be up to the plugin to decide what they want to use.

At the end of the day it's probably easiest if they all pipe data to Bridgetown the same way, but they're free to define how they wish to retrieve it.

jaredcwhite commented 4 years ago

@ParamagicDev Yes, definitely plugins are the way to go…I was just thinking out loud if there's a way to provide a bit of an abstraction layer so the way in which source/content plugins work is somewhat interchangeable. I've been toying a lot lately with GraphQL and to a certain degree it actually is pretty vendor-agonistic which is nice. The schema may change from CMS to CMS, but the way in which you utilize those schemas is quite similar. So we might not have all that much, if anything, to do for this other than simply make it easy for the plugin to turn the source content into the data structures Bridgetown expects.

jaredcwhite commented 4 years ago

Latest experimentation with using GraphQL pulling from Strapi CMS:

https://github.com/jaredcwhite/strapi-and-bridgetown-demo/blob/master/bridgetown/plugins/builders/graphql_builder.rb

(the smarts are up a level in site_builder.rb)

jaredcwhite commented 4 years ago

I think I'm going to turn this into a separate plugin so people can easily pull data from GraphQL data sources. At this point I'm leaning towards closing this issue and considering it "solved" for the time being. The vendor lock-in issue seems less of a concern as tweaking a few queries when moving from one CMS' endpoint to another sounds rather straightforward.

jaredcwhite commented 4 years ago

Closing, as the generic GraphQL plugin approach seems best, and anything more custom can just be a regular one-off plugin.