Eyes on the APIs
How a Gatsby and API-driven architecture can make faster, more secure, and more scalable web projects.
What we'll talk about
- Why APIs?
-
What is GraphQL?
- Building an app with GraphQL + SS CMS
- Building a website with SS CMS + Gatsby
Why APIs?
Clients are like, really into their data.
A content API separates the consumption of content from the delivery of content.
Tooling
What is GraphQL?
GraphQL is a strongly typed query language for your API
GraphQL Fundamentals
- Types have Fields
- Queries return types
- Mutations modify data
- Fields can take arguments
- Fields must resolve.
- Primitive types OOTB, including listOf and nonNull
Using GraphQL in Silverstripe
SS CMS + GraphQL Fundamentals
- Relies on code generation (/dev/graphql/build)
- Autobuild at request time when necessary (e.g. CI)
- Declarative approach (YAML)
- Low-level abstraction layer with smart defaults for Dataobjects
- First production project set to launch in March
Demo
Building an app
- Add GraphQL data to your React components
- Handles network layer
- Client side caching
- Optimistic / implicit updates
- Pluggable / composable
Demo
Building a website with GraphQL
THE SWARM
THE HEARD-OF-ITS
THE CV ITEMS
THE IMPACTFUL
The Fanboy Funnel
Laurie Voss
Founder, NPM
- Serves 11 million developers
- 6 billion package downloads per week
- 97% of app code is sourced from NPM
- Creates more data than it provides
JAMES
Trinidad and Tobago
Simplicity is a core value of web technology.
"So we beat on, boats against the current, borne back ceaselessly into the past."
Technological gravity
"OMG I can do a website using just HTML and CSS"
Gatsby is a static site generator for React.
Server rendered static assets, hydrated to a SPA.
Compiled to static
- Performance
- Security
- Low cost
Then it's dynamic
- User-generated content
- Real time data
- Authenticated / private content
- Declarative behaviours
The best of both worlds...
"What parts of the app need to be dynamic?"
Bring your own data
Guiding principles
1. The App Tuple
HTML
CSS
DATA
+
+
APP
=
(behaviour)
- HTML (Structure)
- CSS (Style)
- Data (Contents)
HTML
DATA
DATA
DATA
CSS
2. The source of your data is just an organisational detail.
3. It's done when you start.
Build
"The right thing is the easy thing."
-
Code splitting
-
Background pre-fetching
-
Image optimisation
-
Lazy loading
Performance
"It's yours to stuff up."
- 100% score on Lighthouse / webpagetest.org
- Service worker
Gatsby OOTB
4. Awesome dev experience
- Just React, GraphQL and your favourite CSS library
- Never worry about builds. Abstracted away.
- Less than 5% of Gatsby projects ever touch the build
5. Invest in the community
Gatsby ❤️ contributors
- Any commit gets free swag.
- Any five commits gets premium swag
- Buy swag at cost. Worldwide shipping free.
- Docs are streamlined to onboard first-time contributors
- Over 1,300 plugins
- Relatively active Discord chat room (no Slack)
What's it like to use Gatsby?
$ gatsby new my-project
cd my-project
gatsby develop
<gatsby-starter-default>
http://localhost:8000
http://localhost:8000/__graphql
Adding data sources
$ yarn add gatsby-source-rss-feed
{
resolve: `gatsby-source-rss-feed`,
options: {
url: `https://silverstripe.org/blog/rss`,
name: `SilverStripeBlog`
}
}
$ gatsby develop
Creating pages
What does this mean for Silverstripe?
docs.silverstripe.org
silverstripe/silverstripe-gatsby
Gatsby source plugin that sources from a site with silverstripe-gatsby installed
gatsby-source-silverstripe
Silverstripe CMS module that exposes all your DataObjects to Gatsby
silverstripe-gatsby-helpers
Lightweight npm package that provides utility functions for working with the Silverstripe CMS source, such as `buildSiteTree()`, `useMenu(1)`
Things to consider
- How do we handle draft content?
- Long build times
- Content blocks
- Form submissions
- CMS Netlify module for user instantiated builds
Also...
Doesn't
silverstripe-graphql SUCK?
YUP.
It really sucks.
How we're fixing GraphQL
The A&D Team
Gets paid to hack on shit.
Yup, sounds like hacking.
yawn.. more bullshit. We get it, you're a hack.
But we're fixing GraphQL!
How we got here
-
GraphQL was the chosen API layer for asset-admin in CMS v4
-
Early adopters, but proven right
-
silverstripe-graphql module tagged stable in CMS 4.0 release
-
Major version releases required
It's slow AF.
GraphQHell
A problem we Graph-Knew-Well
-
Discussions about making the schema cacheable date back nearly two years.
-
Complex problem to solve: Lots of dynamic code
-
Needs of our bespoke teams and partner agencies drive our product roadmap
How we fixed it
Attempt #1: serialize() into submission
It finally serialize()'ed!
unserialize() => 200ms
The problem
The solution
Attempt #2: Code generation
-
Concession: For GraphQL to scale, a build step is inevitable
-
Rewrote scaffolding APIs to generate PHP code
-
~1.2 million layers of abstraction
-
And... it worked!
-
But were performance gains worth the DX penalty?
The problem
The solution
March 2020: Major news breaks.
graphql-php v14.0 released
graphql-php 14.0
-
Small print mentions new lazy type loading API
-
More small print mentions type language support (and caching!)
-
Type language = DX win
-
Type lazy loading = Performance win.
Right?
But we got there.
GraphQL v4 in summary
-
Uses code generation to persist an executable schema to the filesystem
-
Requires a build step
-
Almost everything can be done in YAML
-
Type/Query creators and scaffolders just glorified arrays
-
Scaffolders are now “models” that populate those arrays
-
GraphQL v4 in summary
-
All you’re doing is composing value objects that render themselves in PHP code.
-
Manager is now Schema, and query handling has been isolated out.
-
Plugins distribute single-concern, reusable code
-
Confirmed: We don’t have a schema problem, we have a resolver problem.
The resolver problem
-
Resolvers must be static. (99% of resolvers already are)
-
To reduce boilerplate, a resolver discovery pattern will find resolvers implicitly
-
Resolvers can take context (e.g. for generic DataObject resolvers)
-
($context) => ($obj, $args) => $result
-
-
Classes will define many resolver methods, organised as needed
The Plugin API
-
Just about everything in the Schema accepts plugins:
-
Updates can be a one-type schema-wide update or a very surgical update to one field
-
Example plugins: Versioned, Sort, Filter, Paginate, PermissionCheck
But is it faster?!
Average response time: ~70ms
Our graph-grew-well.
Live code demo.
What the hell. It's not like 2020 can get much worse.
What's next?
-
Backward compat with core modules:
-
Asset-admin
-
Versioned
-
Elemental
-
Versioned-admin / Snapshots
-
-
Refine the DX and devops around the new schema build:
-
Build performance
-
Autobuilding?
-
-
N+1 optimisation, query caching
-
Real world usage
You can help
-
Why aren’t you building more API-driven sites?
-
What can Silverstripe Ltd do to help derisk this?
-
Try it on a small project, or a side project, and give us feeback
GraphQL Lunch & Learn Feb 2021
By Aaron Carlino
GraphQL Lunch & Learn Feb 2021
- 651