SlideShare une entreprise Scribd logo
1  sur  68
Télécharger pour lire hors ligne
Moving to GraphQL
Scott Taylor, The New York Times
GraphQL Summit 2017
San Francisco, CA
The (failing) New
York Times
Scott Taylor
• I live in Brooklyn, NY with my wife, Allie (+ cats)
• Sr. Software Engineer, Web Frameworks

The New York Times
• WordPress core team
• Musician
• @wonderboymusic on Twitter
• @staylor on GitHub
Replatform
Goals
• Simplify our stack

• One place to add and retrieve data 

• Common language / repository for creating / reusing
components

• Make onboarding easier
Our Last
Replatform
Our Last Replatform
• NYT5 - 4 short years ago
• “We are never taking this long on a project
ever again” - our CEO at the champagne
toast celebrating the above.
• (We are taking this long on the project
currently)
So WHY replatform?
• Consistency: Design changes should affect
as few codebases as possible
• Desktop and mobile apps will be one
• iPhone and iPad rewritten as one in Swift
• Android and iOS render WebViews
Technical Notes
• moving Datacenter apps to Google Cloud
Platform

• NYTimes/drone-gke

NYTimes/drone-gae

• Moving data pipeline to internal schema that
uses ProtoBufs / writes to Kafka

• KYT: manages configuration of Node
GraphQL at the NYT
• the GraphQL server is a Sangria app, written
in Scala, maintained by a data team called
Samizdat

• the frontend is a universal Relay (Classic)
app, running on Node/Express, maintained
by the Web Frameworks team
React/GraphQL at
the NYT. Why?
Schema Evolution
Do Not Mirror Legacy Data
(we mirrored legacy data)
Versioning
(we versioned the schema)
Pivots
• initially mirrored REST schema

• versioned the schema / generated from ProtoBufs

• versioned the schema again, driven by product

• after going all in on designing schema using NYT design
terminology, decided to remove some abstractions to
avoid fragment complexity
Relay
• v0.1.0 through 0.7.3 were all released (on GitHub) 

on March 4, 2016

• v0.8.0 was April 2016

• v0.9.0 was May 2016

• v0.9.1 was June 2016

• v0.9.2 was July 2016

• v0.9.3 was September 2016

• v0.10.0 was December 2016
Relay Modern
May 19, 2017
The Road Forward
• Relay Modern

• Apollo
Ecosystem
Relay Classic
• React Router v3

• React Router Relay

• Isomorphic Relay Router

• custom Network Layer
<Route	component={App}>	
		<Route	path="/:id"	component={Story}	queries={{	
				story:	()	=>	Relay.QL`query	{	article(id:	$id)	}`,	
		}}	/>	
		<Route	path="/"	component={Home}	queries={{	
				home:	()	=>	Relay.QL`query	{	home	}`,	
		}}	/>	
</Route>
<Route	component={App}>	
		<Route	path="/:id"	component={Story}	queries={{	
				story:	()	=>	Relay.QL`query	{	article(id:	$id)	}`,	
		}}	/>	
		<Route	path="/"	component={Home}	queries={{	
				home:	()	=>	Relay.QL`query	{	home	}`,	
		}}	/>	
</Route>
<Route	component={App}>	
		<Route	path="/:id"	component={Story}	queries={{	
				story:	()	=>	Relay.QL`query	{	article(id:	$id)	}`,	
		}}	/>	
		<Route	path="/"	component={Home}	queries={{	
				home:	()	=>	Relay.QL`query	{	home	}`,	
		}}	/>	
</Route>
<Route	component={App}>	
		<Route	path="/:id"	component={Story}	queries={{	
				story:	()	=>	Relay.QL`query	{	article(id:	$id)	}`,	
		}}	/>	
		<Route	path="/"	component={Home}	queries={{	
				home:	()	=>	Relay.QL`query	{	home	}`,	
		}}	/>	
</Route>
export	default	Relay.createContainer(CardMedia,	{	
		initialVariables:	{	
				crop:	'jumbo',	
		},	
		fragments:	{	
				media:	({	crop	})	=>	Relay.QL`	
						fragment	CardMedia_media	on	Media	{	
								${Image.getFragment('media',	{	crop	})}	
						}	
				`,	
		},	
});
export	default	Relay.createContainer(Image,	{	
		initialVariables:	{	
				crop:	'jumbo',	
		},	
		fragments:	{	
				media:	()	=>	Relay.QL`	
						fragment	Image_media	on	Image	{	
								crops(renditionNames:	$crop)	{	
										renditions	{	
												name	
												url	
												width	
												height	
										}	
								}	
						}	
				`,	
		},	
});
this.props.relay.setVariables({	isClient:	true	});	
fragment	Component_data	on	Data	{	
		data	
		userData	@include(if:	$isClient)			
}	
this.props.relay.setVariables({	count:	count	+	10	});
export	default	class	RemoveFromReadingListMutation	extends	Relay.Mutation	{	
		getMutation	=	()	=>	Relay.QL`mutation	{	removeFromReadingList	}`;	
		getVariables	=	()	=>	({	
				clientMutationId:	this.props.id,	
				url:	this.props.url,	
				userIdentifier:	{	token	},	
		});	
		getFatQuery	=	()	=>	
				Relay.QL`	
						fragment	on	ReadingListMutationResult	{	
								readingListAssetsConnection(first:	200)	{	
										edges	
								}	
						}	
				`;	
		getConfigs	=	()	=>	[{	
				type:	'NODE_DELETE',	
				parentName:	'readingListAssetsConnection',	
				connectionName:	'readingListAssetsConnection',	
				deletedIDFieldName:	'clientMutationId',	
		}];	
}
import	{	match	}	from	'react-router';	
import	IsomorphicRouter	from	'isomorphic-relay-router';	
import	NYTNetworkLayer	from	'network/NYTNetworkLayer';	
export	default	async	(req,	res,	next)	=>	{	
		match({	routes,	location:	req.url	},	(err,	redirectLocation,	
rootContainerProps)	=>	{	
				const	data	=	await	IsomorphicRouter.prepareData(	
	 		rootContainerProps,	
	 		new	NYTNetworkLayer(req.gqlUrl,	req.gqlConfig)	
	 );	
	 	
	 const	html	=	renderToString(	
	 		<App>	
	 					{IsomorphicRouter.render(data.props)}	
	 		</App>	
	 	);	
	 	
	 ...	
		});	
};
Relay Modern
• Found Relay - 0.3.0-alpha.9

• <QueryRenderer	/> is not
isomorphic

• custom fetch( ) +
QueryResponseCache
export	const	routeConfig	=	makeRouteConfig(	
		<Route	
				path="/"	
				Component={App}	
				query={AppQuery}>	
				<Route	
						Component={Home}	
						query={HomeQuery}	
						render={renderProp}	
				/>	
		</Route>	
);
const	source	=	new	RecordSource();	
const	store	=	new	Store(source);	
const	network	=	Network.create(fetchQuery);	
const	environment	=	new	Environment({	
		network,	
		store,	
});	
export	default	environment;
export	default	createFragmentContainer(CardMedia,	{	
		media:	graphql`	
				fragment	CardMedia_media	on	Media	{	
...Image_media	
				}	
		`,	
});
import	{	graphql	}	from	'react-relay';	
export	default	graphql`	
		query	Story_Query($id:	ID!,	$crop:	[CropName!]!)	{	
				...Story_viewer	
		}	
`;
createRefetchContainer(Component,	graphql`…`);	
this.props.relay.refetch({	searchTerm:	'tacos'	});
export	default	createPaginationContainer(	
		Term,	
		graphql`	
				fragment	Term_viewer	on	Viewer	{	
						term(slug:	$slug,	taxonomy:	$taxonomy)	{	
								id	
								name	
								slug	
						}	
						posts(term:	$slug,	after:	$cursor,	first:	$count)	@connection(key:	"Term_posts")	{	
								edges	{	
										node	{	
												...Post_post	
										}	
										cursor	
								}	
								pageInfo	{	
										startCursor	
										endCursor	
										hasNextPage	
										hasPreviousPage	
								}	
						}	
				}	
		`,	
		{	
				direction:	'forward',	
				getConnectionFromProps(props)	{	
						return	props.viewer	&&	props.viewer.posts;	
				},	
				getVariables(props,	{	count,	cursor	},	fragmentVariables)	{	
						return	{	
								...fragmentVariables,	
								count,	
								cursor,	
						};	
				},	
				getFragmentVariables(vars,	totalCount)	{	
						return	{	
								...vars,	
								count:	totalCount,	
						};	
				},	
				query:	TermQuery,	
		}	
);
this.props.relay.loadMore(10)
const	updater	=	store	=>	{	
		const	payload	=	store.getRootField('addComment');	
		const	newComment	=	payload.getLinkedRecord('comment');	
		if	(!newComment)	{	
				return;	
		}	
		const	post	=	store.get(variables.input.post);	
		const	connection	=	ConnectionHandler.getConnection(	
				post,		
				'Single_post_comments',	{	
						post:	variables.input.post,	
				}	
		);	
		const	newEdge	=	ConnectionHandler.createEdge(	
				store,	connection,	newComment,	'CommentEdge');	
		ConnectionHandler.insertEdgeAfter(connection,	newEdge);	
};
so now what?
Apollo
Apollo
• use any Router you want

• no need to customize network

• SSR/Store rehydration requires
very little setup
export	default	(	
		<Route	path="/"	component={App}>	
				<Route	path="/:id"	component={Story}	/>	
				<Route	component={Home}	/>	
		</Route>	
);
const	client	=	new	ApolloClient({	
						ssrMode:	true,	
						networkInterface:	networkInterface(uri),	
						fragmentMatcher,	
				});	
				const	app	=	(	
						<ApolloProvider	client={client}>	
								<App	/>	
						</ApolloProvider>	
				);	
				getDataFromTree(app).then(()	=>	{	
						const	html	=	renderToString(app);	
						.	.	.	
				});
const	client	=	new	ApolloClient({	
						initialState:	window.__APOLLO_STATE__,	
						networkInterface:	networkInterface('/graphql'),	
						fragmentMatcher,	
				});	
				ReactDOM.hydrate(	
						<App	/>,	
						document.getElementById('main')	
				);
@graphql(HomeQuery,	{	
		options:	{	
				variables:	{	
						crop:	'jumbo',	
				},	
		},	
})	
export	default	class	Home	extends	Component	{	
		render()	{	
				const	{	data:	{	loading,	error	}	}	=	this.props;	
				if	(error)	{	
						return	<Error	/>;	
				}	else	if	(loading)	{	
						return	<Loading	/>;	
				}	
				const	{	viewer	}	=	this.props.data;	
				.	.	.	
		}	
}
@graphql(HomeQuery,	{	
		options:	{	
				ssr:	false,	
		},	
})	
export	default	class	Home	extends	Component	{	
...	
}
Apollo Options
• import	{	gql	}	from	'react-apollo'	
• import	gql	from	'graphql-tag'	
• .graphql files 

• babel-plugin-inline-import-graphql-ast	
• graphql-tag/loader
export	default	function	Media()	{	
		.	.	.	
}	
Media.fragments	=	{	
		node:	gql`	
				fragment	Media_node	on	Media	{	
						id	
						url	
				}	
		`,	
};
export	default	function	Media()	{	
		.	.	.	
}	
Media.fragments	=	{	
		node:	gql`	
				fragment	Media_node	on	Media	{	
						id	
						url	
						...	on	Image	{	
								...Image_node	
						}	
				}	
${Image.fragments.node}		
		`,	
};
#import	"./Archive_posts.graphql"	
query	Term_Query(	
		$slug:	String!,		
		$cursor:	String,		
		$count:	Int	
)	{	
		viewer	{	
				term(slug:	$slug)	{	
						id	
						name	
						slug	
				}	
				posts(term:	$slug,	after:	$cursor,	first:	$count)	{	
						...Archive_posts	
				}	
		}	
}
this.props.data.refetch({	…	})	
this.props.data.fetchMore({	…	})
Isomorphic
React/GraphQL
The Problem with
HTML in React
and GraphQL
Structured Data
• Union types: BlockUnion and InlineUnion

• fragments and queries can become enormous when
using heterogenous types

• recursion of unknown/infinite depth is a problem in
GraphQL
Scripts in HTML
• JavaScript will not execute when simply:



<div	dangerouslySetInnerHTML={{	__html:	content	}}	/>

• Scripts need to be parsed out of content and intialized/re-
initialized on: componentDidMount / componentDidUpdate

• Server-rendering scripts - nodes get blown away on 



ReactDOM.{render,hydrate}
Roadmap
• Moving to React 16, adjusting to the ecosystem

• Continue following developments with Relay/Apollo

• Continue evolving our schema

• CSS-in-JS (!!!), Emotion and friends
We're Hiring!
•All jobs: 

https://nytimes.wd5.myworkdayjobs.com/NYT/
•Home team: 

https://nytimes.wd5.myworkdayjobs.com/NYT/job/New-York-NY/
Engineer---News-Products_REQ-001556-2
•Story team: 

https://nytimes.wd5.myworkdayjobs.com/en-US/Tech/job/New-York-NY/
Engineer---News-Products_REQ-001556
•Data team (come talk to us!): GraphQL, Scala, Finagle
Thank You.

Contenu connexe

Similaire à The New York Times: Moving to GraphQL

Rez gateway - RezOS - innovate the future
Rez gateway - RezOS -   innovate the futureRez gateway - RezOS -   innovate the future
Rez gateway - RezOS - innovate the futureindikaMaligaspe
 
Rez gateway (RezOS) innovate the future
Rez gateway  (RezOS) innovate the futureRez gateway  (RezOS) innovate the future
Rez gateway (RezOS) innovate the futureindikaMaligaspe
 
ReliefWeb | DevSeed Meeting | 03 Sep 2010
ReliefWeb | DevSeed Meeting | 03 Sep 2010ReliefWeb | DevSeed Meeting | 03 Sep 2010
ReliefWeb | DevSeed Meeting | 03 Sep 2010ReliefWeb
 
React native - React(ive) Way To Build Native Mobile Apps
React native - React(ive) Way To Build Native Mobile AppsReact native - React(ive) Way To Build Native Mobile Apps
React native - React(ive) Way To Build Native Mobile AppsJimit Shah
 
MEAN Stack Warm-up
MEAN Stack Warm-upMEAN Stack Warm-up
MEAN Stack Warm-upTroy Miles
 
SharePoint Fest Chicago 2018 - From SharePoint to Office 365 development
SharePoint Fest Chicago 2018 - From SharePoint to Office 365 developmentSharePoint Fest Chicago 2018 - From SharePoint to Office 365 development
SharePoint Fest Chicago 2018 - From SharePoint to Office 365 developmentSébastien Levert
 
aOS Canadian Tour - Quebec - From SharePoint to Office 365 Development
aOS Canadian Tour  - Quebec - From SharePoint to Office 365 DevelopmentaOS Canadian Tour  - Quebec - From SharePoint to Office 365 Development
aOS Canadian Tour - Quebec - From SharePoint to Office 365 DevelopmentSébastien Levert
 
aOS Canadian Tour - Ottawa - From SharePoint to Office 365 Development
aOS Canadian Tour - Ottawa - From SharePoint to Office 365 DevelopmentaOS Canadian Tour - Ottawa - From SharePoint to Office 365 Development
aOS Canadian Tour - Ottawa - From SharePoint to Office 365 DevelopmentSébastien Levert
 
aOS Canadian Tour - Montreal - From SharePoint to Office 365 Development
aOS Canadian Tour - Montreal - From SharePoint to Office 365 DevelopmentaOS Canadian Tour - Montreal - From SharePoint to Office 365 Development
aOS Canadian Tour - Montreal - From SharePoint to Office 365 DevelopmentSébastien Levert
 
aOS Canadian Tour - Toronto - From SharePoint to Office 365 Development
aOS Canadian Tour - Toronto - From SharePoint to Office 365 DevelopmentaOS Canadian Tour - Toronto - From SharePoint to Office 365 Development
aOS Canadian Tour - Toronto - From SharePoint to Office 365 DevelopmentSébastien Levert
 
SharePoint Fest DC 2019 - From SharePoint to Office 365 Development
SharePoint Fest DC 2019 - From SharePoint to Office 365 DevelopmentSharePoint Fest DC 2019 - From SharePoint to Office 365 Development
SharePoint Fest DC 2019 - From SharePoint to Office 365 DevelopmentSébastien Levert
 
SharePoint Fest Seattle 2019 - From SharePoint to Office 365 Development
SharePoint Fest Seattle 2019 - From SharePoint to Office 365 DevelopmentSharePoint Fest Seattle 2019 - From SharePoint to Office 365 Development
SharePoint Fest Seattle 2019 - From SharePoint to Office 365 DevelopmentSébastien Levert
 
Introducing ASP.NET vNext – The Future of .NET on the Server | FalafelCON 2014
Introducing ASP.NET vNext – The Future of .NET on the Server | FalafelCON 2014Introducing ASP.NET vNext – The Future of .NET on the Server | FalafelCON 2014
Introducing ASP.NET vNext – The Future of .NET on the Server | FalafelCON 2014FalafelSoftware
 
Vincent biret azure functions and flow (toronto)
Vincent biret azure functions and flow (toronto)Vincent biret azure functions and flow (toronto)
Vincent biret azure functions and flow (toronto)Vincent Biret
 
Vincent biret azure functions and flow (ottawa)
Vincent biret azure functions and flow (ottawa)Vincent biret azure functions and flow (ottawa)
Vincent biret azure functions and flow (ottawa)Vincent Biret
 
Introducing ASP.NET vNext - A tour of the new ASP.NET platform
Introducing ASP.NET vNext - A tour of the new ASP.NET platformIntroducing ASP.NET vNext - A tour of the new ASP.NET platform
Introducing ASP.NET vNext - A tour of the new ASP.NET platformJeffrey T. Fritz
 
SharePoint Fest Seattle 2018 - From SharePoint to Office 365 Development
SharePoint Fest Seattle 2018 - From SharePoint to Office 365 DevelopmentSharePoint Fest Seattle 2018 - From SharePoint to Office 365 Development
SharePoint Fest Seattle 2018 - From SharePoint to Office 365 DevelopmentSébastien Levert
 
ESPC Webinar - From SharePoint to Office 365 Development
ESPC Webinar - From SharePoint to Office 365 DevelopmentESPC Webinar - From SharePoint to Office 365 Development
ESPC Webinar - From SharePoint to Office 365 DevelopmentSébastien Levert
 
How we use the play framework
How we use the play frameworkHow we use the play framework
How we use the play frameworkItai Gilo
 

Similaire à The New York Times: Moving to GraphQL (20)

Rez gateway - RezOS - innovate the future
Rez gateway - RezOS -   innovate the futureRez gateway - RezOS -   innovate the future
Rez gateway - RezOS - innovate the future
 
Rez gateway (RezOS) innovate the future
Rez gateway  (RezOS) innovate the futureRez gateway  (RezOS) innovate the future
Rez gateway (RezOS) innovate the future
 
ReliefWeb | DevSeed Meeting | 03 Sep 2010
ReliefWeb | DevSeed Meeting | 03 Sep 2010ReliefWeb | DevSeed Meeting | 03 Sep 2010
ReliefWeb | DevSeed Meeting | 03 Sep 2010
 
React native - React(ive) Way To Build Native Mobile Apps
React native - React(ive) Way To Build Native Mobile AppsReact native - React(ive) Way To Build Native Mobile Apps
React native - React(ive) Way To Build Native Mobile Apps
 
MEAN Stack Warm-up
MEAN Stack Warm-upMEAN Stack Warm-up
MEAN Stack Warm-up
 
SharePoint Fest Chicago 2018 - From SharePoint to Office 365 development
SharePoint Fest Chicago 2018 - From SharePoint to Office 365 developmentSharePoint Fest Chicago 2018 - From SharePoint to Office 365 development
SharePoint Fest Chicago 2018 - From SharePoint to Office 365 development
 
aOS Canadian Tour - Quebec - From SharePoint to Office 365 Development
aOS Canadian Tour  - Quebec - From SharePoint to Office 365 DevelopmentaOS Canadian Tour  - Quebec - From SharePoint to Office 365 Development
aOS Canadian Tour - Quebec - From SharePoint to Office 365 Development
 
aOS Canadian Tour - Ottawa - From SharePoint to Office 365 Development
aOS Canadian Tour - Ottawa - From SharePoint to Office 365 DevelopmentaOS Canadian Tour - Ottawa - From SharePoint to Office 365 Development
aOS Canadian Tour - Ottawa - From SharePoint to Office 365 Development
 
aOS Canadian Tour - Montreal - From SharePoint to Office 365 Development
aOS Canadian Tour - Montreal - From SharePoint to Office 365 DevelopmentaOS Canadian Tour - Montreal - From SharePoint to Office 365 Development
aOS Canadian Tour - Montreal - From SharePoint to Office 365 Development
 
aOS Canadian Tour - Toronto - From SharePoint to Office 365 Development
aOS Canadian Tour - Toronto - From SharePoint to Office 365 DevelopmentaOS Canadian Tour - Toronto - From SharePoint to Office 365 Development
aOS Canadian Tour - Toronto - From SharePoint to Office 365 Development
 
SharePoint Fest DC 2019 - From SharePoint to Office 365 Development
SharePoint Fest DC 2019 - From SharePoint to Office 365 DevelopmentSharePoint Fest DC 2019 - From SharePoint to Office 365 Development
SharePoint Fest DC 2019 - From SharePoint to Office 365 Development
 
SharePoint Fest Seattle 2019 - From SharePoint to Office 365 Development
SharePoint Fest Seattle 2019 - From SharePoint to Office 365 DevelopmentSharePoint Fest Seattle 2019 - From SharePoint to Office 365 Development
SharePoint Fest Seattle 2019 - From SharePoint to Office 365 Development
 
Introducing ASP.NET vNext – The Future of .NET on the Server | FalafelCON 2014
Introducing ASP.NET vNext – The Future of .NET on the Server | FalafelCON 2014Introducing ASP.NET vNext – The Future of .NET on the Server | FalafelCON 2014
Introducing ASP.NET vNext – The Future of .NET on the Server | FalafelCON 2014
 
Vincent biret azure functions and flow (toronto)
Vincent biret azure functions and flow (toronto)Vincent biret azure functions and flow (toronto)
Vincent biret azure functions and flow (toronto)
 
Vincent biret azure functions and flow (ottawa)
Vincent biret azure functions and flow (ottawa)Vincent biret azure functions and flow (ottawa)
Vincent biret azure functions and flow (ottawa)
 
Introducing ASP.NET vNext - A tour of the new ASP.NET platform
Introducing ASP.NET vNext - A tour of the new ASP.NET platformIntroducing ASP.NET vNext - A tour of the new ASP.NET platform
Introducing ASP.NET vNext - A tour of the new ASP.NET platform
 
SharePoint Fest Seattle 2018 - From SharePoint to Office 365 Development
SharePoint Fest Seattle 2018 - From SharePoint to Office 365 DevelopmentSharePoint Fest Seattle 2018 - From SharePoint to Office 365 Development
SharePoint Fest Seattle 2018 - From SharePoint to Office 365 Development
 
SamSegalResume
SamSegalResumeSamSegalResume
SamSegalResume
 
ESPC Webinar - From SharePoint to Office 365 Development
ESPC Webinar - From SharePoint to Office 365 DevelopmentESPC Webinar - From SharePoint to Office 365 Development
ESPC Webinar - From SharePoint to Office 365 Development
 
How we use the play framework
How we use the play frameworkHow we use the play framework
How we use the play framework
 

Plus de Scott Taylor

Internationalizing The New York Times
Internationalizing The New York TimesInternationalizing The New York Times
Internationalizing The New York TimesScott Taylor
 
REST In Action: The Live Coverage Platform at the New York Times
REST In Action: The Live Coverage Platform at the New York TimesREST In Action: The Live Coverage Platform at the New York Times
REST In Action: The Live Coverage Platform at the New York TimesScott Taylor
 
WordPress 4.4 and Beyond
WordPress 4.4 and BeyondWordPress 4.4 and Beyond
WordPress 4.4 and BeyondScott Taylor
 
2015 WordCamp Maine Keynote
2015 WordCamp Maine Keynote2015 WordCamp Maine Keynote
2015 WordCamp Maine KeynoteScott Taylor
 
Live Coverage at The New York Times
Live Coverage at The New York TimesLive Coverage at The New York Times
Live Coverage at The New York TimesScott Taylor
 
WordPress: Getting Under the Hood
WordPress: Getting Under the HoodWordPress: Getting Under the Hood
WordPress: Getting Under the HoodScott Taylor
 
WordPress Media in a post-Koop Universe
WordPress Media in a post-Koop UniverseWordPress Media in a post-Koop Universe
WordPress Media in a post-Koop UniverseScott Taylor
 
Cloud, Cache, and Configs
Cloud, Cache, and ConfigsCloud, Cache, and Configs
Cloud, Cache, and ConfigsScott Taylor
 
eMusic: WordPress in the Enterprise
eMusic: WordPress in the EnterpriseeMusic: WordPress in the Enterprise
eMusic: WordPress in the EnterpriseScott Taylor
 
WordPress Front End Optimizations
WordPress Front End OptimizationsWordPress Front End Optimizations
WordPress Front End OptimizationsScott Taylor
 

Plus de Scott Taylor (11)

Internationalizing The New York Times
Internationalizing The New York TimesInternationalizing The New York Times
Internationalizing The New York Times
 
A Day of REST
A Day of RESTA Day of REST
A Day of REST
 
REST In Action: The Live Coverage Platform at the New York Times
REST In Action: The Live Coverage Platform at the New York TimesREST In Action: The Live Coverage Platform at the New York Times
REST In Action: The Live Coverage Platform at the New York Times
 
WordPress 4.4 and Beyond
WordPress 4.4 and BeyondWordPress 4.4 and Beyond
WordPress 4.4 and Beyond
 
2015 WordCamp Maine Keynote
2015 WordCamp Maine Keynote2015 WordCamp Maine Keynote
2015 WordCamp Maine Keynote
 
Live Coverage at The New York Times
Live Coverage at The New York TimesLive Coverage at The New York Times
Live Coverage at The New York Times
 
WordPress: Getting Under the Hood
WordPress: Getting Under the HoodWordPress: Getting Under the Hood
WordPress: Getting Under the Hood
 
WordPress Media in a post-Koop Universe
WordPress Media in a post-Koop UniverseWordPress Media in a post-Koop Universe
WordPress Media in a post-Koop Universe
 
Cloud, Cache, and Configs
Cloud, Cache, and ConfigsCloud, Cache, and Configs
Cloud, Cache, and Configs
 
eMusic: WordPress in the Enterprise
eMusic: WordPress in the EnterpriseeMusic: WordPress in the Enterprise
eMusic: WordPress in the Enterprise
 
WordPress Front End Optimizations
WordPress Front End OptimizationsWordPress Front End Optimizations
WordPress Front End Optimizations
 

Dernier

Git and Github workshop GDSC MLRITM
Git and Github  workshop GDSC MLRITMGit and Github  workshop GDSC MLRITM
Git and Github workshop GDSC MLRITMgdsc13
 
Contact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New DelhiContact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New Delhimiss dipika
 
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja VipCall Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja VipCall Girls Lucknow
 
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Dana Luther
 
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书zdzoqco
 
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170Sonam Pathan
 
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)Christopher H Felton
 
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012Call Girls South Delhi Delhi reach out to us at ☎ 9711199012
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012rehmti665
 
Blepharitis inflammation of eyelid symptoms cause everything included along w...
Blepharitis inflammation of eyelid symptoms cause everything included along w...Blepharitis inflammation of eyelid symptoms cause everything included along w...
Blepharitis inflammation of eyelid symptoms cause everything included along w...Excelmac1
 
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作ys8omjxb
 
Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Paul Calvano
 
Magic exist by Marta Loveguard - presentation.pptx
Magic exist by Marta Loveguard - presentation.pptxMagic exist by Marta Loveguard - presentation.pptx
Magic exist by Marta Loveguard - presentation.pptxMartaLoveguard
 
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一z xss
 
Film cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasaFilm cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasa494f574xmv
 
Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Sonam Pathan
 
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一Fs
 

Dernier (20)

Git and Github workshop GDSC MLRITM
Git and Github  workshop GDSC MLRITMGit and Github  workshop GDSC MLRITM
Git and Github workshop GDSC MLRITM
 
Contact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New DelhiContact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New Delhi
 
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja VipCall Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
 
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
 
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Serviceyoung call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
 
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
 
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
 
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
 
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
 
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012Call Girls South Delhi Delhi reach out to us at ☎ 9711199012
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012
 
Model Call Girl in Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in  Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝Model Call Girl in  Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
 
Blepharitis inflammation of eyelid symptoms cause everything included along w...
Blepharitis inflammation of eyelid symptoms cause everything included along w...Blepharitis inflammation of eyelid symptoms cause everything included along w...
Blepharitis inflammation of eyelid symptoms cause everything included along w...
 
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
 
Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24
 
Magic exist by Marta Loveguard - presentation.pptx
Magic exist by Marta Loveguard - presentation.pptxMagic exist by Marta Loveguard - presentation.pptx
Magic exist by Marta Loveguard - presentation.pptx
 
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
 
Hot Sexy call girls in Rk Puram 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in  Rk Puram 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in  Rk Puram 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Rk Puram 🔝 9953056974 🔝 Delhi escort Service
 
Film cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasaFilm cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasa
 
Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170
 
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一
 

The New York Times: Moving to GraphQL