104 |
105 |
106 |
107 | Lately, I've been traveling around the world to conferences and
108 | workshops and I hear common themes emerge. Often the people I meet
109 | are frontend developers. They're really excited about GraphQL and
110 | all the benefits they'd stand to gain but they're having trouble
111 | adopting it in their own organization. These frontend developers are
112 | also usually concerned about building a GraphQL server.
113 |
114 |
115 | On the other hand, the backend developers are usually not as
116 | excited. They're more skeptical and rightfully so since GraphQL's
117 | focus on the product represents a huge shift in their workflow.
118 | They're mostly concerned about performance, caching, and maintaining
119 | control over their services.
120 |
121 | The road to adoption 🛣
122 |
123 |
124 |
128 |
129 |
130 |
131 |
132 | This disagreement between frontend and backend engineers can stall
133 | progress on GraphQL adoption for months, or maybe even years as was
134 | the case at Airbnb. We need a way to find a compromise here.
135 |
136 |
137 |
141 |
147 | - @AdamRNeary, "Reconciling GraphQL and Thrift at Airbnb"
148 |
149 |
150 |
151 |
152 |
153 | The benefits of GraphQL are hard to deny. We're building for mobile,
154 | wearables, VR, IOT - all separate clients requesting data from a
155 | multitude of different microservices. We have to meet our users
156 | where they are so we have to keep building for new platforms and
157 | duplicating logic across clients. GraphQL prevents this situation
158 | from spiraling out of control.
159 |
160 | Our apps are data driven
161 |
162 |
163 |
164 |
165 | GraphQL also fosters collaboration between frontend and backend
166 | teams. When the schema is a contract that both sides can adhere to,
167 | each side can work independently with a common goal in mind. The
168 | frontend doesn't even need to wait on backend changes to be
169 | productive - they can mock out the schema and keep developing Query
170 | components before the data fetching logic is finalized.
171 |
172 | GraphQL fosters collaboration
173 |
174 |
175 |
176 |
177 | Perhaps one of the greatest benefits is how GraphQL clients can
178 | reduce the complexity managing state from within your application.
179 | Instead of writing complex code for fetching and transforming the
180 | data into the shape you need, you just create a GraphQL query.
181 | Apollo client will take care of making the request, caching it,
182 | tracking loading and error state, as well as updating your UI.
183 | Whether your favorite client is Apollo, Relay, or Urql, I think we
184 | all can agree that managing state with any GraphQL client is a hell
185 | of a lot better than rolling your own solution with REST and Redux.
186 |
187 | Apollo reduces complexity
188 |
189 |
190 |
191 |
192 | So how do we bridge the gap between frontend and backend developers?
193 | To figure out a solution, we have to look at their motivations and
194 | find some common ground.
195 |
196 |
197 | Frontend devs want to have a say in what happens with their GraphQL
198 | API because they're the ones using it. Often, they're also the ones
199 | tasked with building an initial server implementation or POC, so
200 | they need an excellent out of the box server experience. They also
201 | are heavily concerned with identifying and following best practices
202 | for things like auth, testing, and schema design.
203 |
204 |
205 | On the other hand, backend developers want to ensure that their
206 | underlying services won't suffer performance hits as a result of
207 | introducing GraphQL. They're worried about things caching and
208 | monitoring.
209 |
210 | Bridging the gap
211 |
212 |
213 |
214 |
215 |
219 |
220 |
221 |
222 |
223 | Their common ground here is the server. If we can design a better
224 | server experience, complete with advanced tooling to satisfy backend
225 | developers and a great getting started experience for the frontend
226 | developers, maybe we can speed up GraphQL adoption as a whole.
227 |
228 |
229 | At Apollo, this is exactly what was on our mind as we started to
230 | plan the next generation of Apollo Server.
231 |
232 |
241 | We need a better server experience in order to
242 |
249 | accelerate adoption.
250 |
251 |
252 |
253 |
254 |
255 | Up until now, I've used the term GraphQL server but sometimes I
256 | think the word server can be intimidating, especially for frontend
257 | developers just getting started. I think it's more accurate to call
258 | it a GraphQL layer since it often sits on top of your existing data
259 | sources. We need to lower the barrier of entry to building this
260 | layer so its achievable by product teams, since GraphQL APIs are at
261 | their best when the product team using them has input into the
262 | design.
263 |
264 |
265 | GraphQL{' '}
266 | server layer
267 |
268 |
269 |
270 |
271 |
272 | Layering GraphQL on top of REST is many developers' first experience
273 | with GraphQL, so we wanted to make this experience better. One of
274 | the best parts of GraphQL is that it doesnt require an entire
275 | rewrite. You can migrate incrementally and rather quickly by
276 | building a GraphQL server over your existing REST endpoints. One
277 | common pain point is caching however. Teams don't want to have to
278 | totally reimplement their existing caching logic when switching to
279 | GraphQL.
280 |
281 | GraphQL over REST
282 |
283 |
284 |
285 |
286 |
287 |
288 | {[
289 | 'Start with the APIs you already have & migrate incrementally',
290 | 'Fastest path to adoption for product developers',
291 | 'What about existing caching strategies already in place?',
292 | ].map(item => (
293 |
294 | {item}
295 |
296 | ))}
297 |
298 |
299 |
300 |
301 |
302 |
303 | Additionally, we needed a better out of the box experience. We were
304 | inspired by what Prisma did with graphql-yoga to connect the dots
305 | between APollo Server, graphql-tools and graphql-subscriptions to
306 | create an excellent getting started experience for GraphQL beginners
307 | and seasoned experts.
308 |
309 | A simpler API
310 |
311 |
318 |
319 |
320 |
321 |
322 |
323 | Ultimately, our goal for the next version of Apollo Server was to
324 | make developing this GraphQL layer approachable for everyone. We
325 | wanted to enable product developers to get GraphQL running quickly
326 | and give them the confidence they needed in order to actually ship
327 | their layer to production. With this goal in mind, we set out to
328 | totally revamp the Apollo Server experience. After a few weeks in
329 | beta and hearing all of your feedback, we're so excited to announce
330 |
331 |
340 | We want to make
341 | developing a GraphQL layer
342 |
343 | approachable
344 | {' '}
345 | for everyone.
346 |
347 |
348 |
349 |
350 | that Apollo Server 2.0 is officially out of beta!! If you haven't
351 | tried it yet, I think you're really going to love it. Let's take a
352 | look at some of the new features
353 |
354 |
355 | Apollo Server 2.0
356 |
366 | New release candidate out today 🎉
367 |
368 |
369 |
370 |
371 |
372 | Instead of giving you separate tools that you'd have to fit together
373 | yourself, Apollo Server wires everything up for you already based on
374 | years of best practices. With only a couple lines of code, you can
375 | set up an GraphQL server in minutes. Out of the box, you get an
376 | Express server that includes our new error management features, as
377 | well as a health check endpoint, and advanced features like
378 | subscriptions and schema stitching already set up for you.
379 |
380 | Apollo Server 2.0 🎉
381 |
382 |
388 |
389 | {[
390 | 'Standard patterns based on best practices, all wired up',
391 | 'Includes error management & a health check endpoint',
392 | 'Supports subscriptions, schema stitching, & file uploads out of the box',
393 | ].map(item => (
394 |
395 | {item}
396 |
397 | ))}
398 |
399 |
400 |
401 |
402 |
403 | I want to talk a little about the new error handling primitives
404 | because they not only improve the developer experience working with
405 | GraphQL, they also get us to speak the same language about errors.
406 | Now you can throw an AuthorizationError for example in a resolver.
407 | This new error primitive uses the extensions.code property to
408 | produce a human readable status code, which you can check in an
409 | Apollo Link on the frontend to implement a reauth flow. For more
410 | information, check out the announcement post by one of our interns
411 | CLarence. I'll send out the links to the all the articles I
412 | reference on my Twitter after the talk.
413 |
414 | Intuitive error handling 🚀
415 |
416 |
417 |
418 | Check out the blog post by @clarencengohpy!
419 |
420 |
421 |
422 |
427 |
428 | With Apollo Server 2.0, you also get GraphQL Playground
429 | automatically set up for you. Shoutout to the Prisma team for their
430 | hard work on GraphQL Playground, it continues to be my favorite way
431 | to test queries and teach developers about GraphQL.
432 |
433 |
434 |
435 |
436 | Also included in Apollo Server 2.0 are some production-ready
437 | features guaranteed to please even the most skeptical backend
438 | engineers on your team! We really wanted performance to be a first
439 | class feature of Apollo Server 2.0, so we included response caching
440 | via the cache controld directive and reporting to Apollo Engine.
441 |
442 |
443 | Production-ready features
444 |
454 | Caching and reporting to Apollo Engine, now included in
455 | Apollo Server! 😍
456 |
457 |
458 |
459 |
460 |
461 | Apollo Engine is our cloud service that provides deep insights into
462 | the performance of your GraphQL server. It has never been easier to
463 | set up Engine than it is now. Just provide an API key as an
464 | environment variable and Apollo Server will do all the heavy lifting
465 | for you. Some of the great features that used to require the engine
466 | proxy before are now enabled by default in Apollo Server. They're
467 | 100% open source. Another one of those features is
468 |
469 |
470 |
471 |
472 |
473 | Automatic persisted queries! All you have to do to complete the
474 | setup process is add the persisted queries link to your Apollo Link
475 | chain. This allows you to send a hash instead of the full query
476 | text, which improves network performance. It's also useful for
477 | sending queries as GET requests, which allows you to cache them with
478 | a CDN.
479 |
480 | Automatic persisted queries
481 |
482 |
483 |
484 | {[
485 | 'On the client, add Apollo Link Persisted Queries to turn on persisted queries',
486 | 'Hashed queries can be sent as GET requests, enabling CDN caching',
487 | ].map(item => (
488 |
489 | {item}
490 |
491 | ))}
492 |
493 |
494 |
495 |
496 |
497 | Don't worry if this sounds like a lot of information - We're also
498 | excited to announce a new docs site for Apollo Server 2.0 which will
499 | guide you through all the latest features! Jani, if you're tuning in
500 | on the live stream, this one's for you. All the new features are
501 | already documented and we're hoping to add more interactive examples
502 | on Glitch in the weeks leading up to the final release.
503 |
504 |
510 |
514 |
515 | https://www.apollographql.com/docs/apollo-server/v2/
516 |
517 |
518 |
519 |
520 |
521 | Where do we go from here? The last part of this talk is going to
522 | cover how we see the future of GraphQL servers evolving over the
523 | next year and how Apollo Server 2.0 moves us in that direction.
524 |
525 |
534 | What's{' '}
535 |
542 | next?
543 |
544 |
545 |
546 |
547 |
548 | Ultimately, our goal is to enable all developers, whether they're
549 | frontend or backend, to create a product focused API and ship it to
550 | production. What's next on the path toward that goal?
551 |
552 |
561 | We want to enable all developers to create a
562 |
569 | product-focused{' '}
570 |
571 | API.
572 |
573 |
574 |
575 |
576 | Wrapping a REST endpoint is often the fastest path to GraphQL
577 | adoption, but the best way to achieve that hasn't always been clear
578 | until now. I couldn't be more excited about the work Martijn has
579 | been doing on the new Apollo Server Data Source API. It's a new way
580 | to wrap REST endpoints that takes care of all the data fetching code
581 | for you so you just have to worry about writing business logic. It
582 | also comes with a shared cache in order to enable whole and partial
583 | query caching. One of the coolest features is that it picks up on
584 | existing cache hints from within your REST response's headers so you
585 | can reuse existing caching logic if you'd like. You also have the
586 | option of specifying cache hints on the schema using the
587 | cachecontrol directive.
588 |
589 |
590 |
591 |
592 |
593 | Apollo Server Data Source
594 |
595 |
596 | {[
597 | 'Easiest way to wrap a REST endpoint with GraphQL',
598 | 'Shared cache for whole and partial query caching',
599 | 'Existing cache-control hints are automatically tied to the fields in your schema',
600 | ].map(item => (
601 |
602 | {item}
603 |
604 | ))}
605 |
606 |
607 |
608 |
609 |
610 |
611 | Let's take a look at an example! Just extend from the REST data
612 | source class and you'll have access to data fetching primitives, as
613 | well as the context if you'd like to set headers from within the
614 | data source.
615 |
616 | We're also planning on introducing features like error metrics and
617 | tracing grouped by data source, which will allow you to gain full
618 | visibility into what's happening with your data sources in Apollo
619 | Engine. The new data source API is available for you to play with in
620 | the new release candidate - definitely try it out and let us know
621 | what you think!
622 |
623 | Apollo Server Data Source
624 |
625 |
632 |
633 | {[
634 | 'Includes data fetching primitives so you only have to supply an endpoint',
635 | 'Allows developers to focus on business logic',
636 | 'Coming soon: deduplication, error handling, per source tracing & metrics 🙌',
637 | ].map((item, idx) => (
638 |
639 | {item}
640 |
641 | ))}
642 |
643 |
644 |
645 |
646 |
647 | I've used the term partial query caching a couple times, let's see
648 | what it actually looks like. It's helpful for data that's a mix of
649 | static and dynamic, for example, we have mostly static movie data
650 | with a dynamic playback rate attached. This query is calling a REST
651 | endpoint wrapped with the Apollo Server data source API. Here's what
652 | this query looks like when you first run it. Notice all the resolver
653 | tracing metrics at the bottom.
654 |
655 |
656 |
657 |
658 |
659 | The second time you run it, all the static data is already cached
660 | and we only have to fetch the dynamic data, as you can see from the
661 | resolver tracing stats at the bottom. This is partial query caching
662 | at work thanks to the Apollo Server Data Source API.
663 |
664 |
665 |
666 |
667 |
668 | Data Sources simplify server development at the bottom of the stack,
669 | but what can we do to simplify development at the schema level? How
670 | do we ensure that changes to our schema don't break our UI? That's
671 | where Apollo's new schema management tools come in. Just specify a
672 | list of validation rules for your schema and Apollo Server will
673 | check each change you make against those rules. This allows you to
674 | refactor, add fields, deprecate fields, and clean up code with
675 | confidence that you haven't broken anything.
676 |
677 |
678 |
683 |
684 |
685 | Collaboration across the stack
686 |
687 |
688 | {[
689 | 'New tools to validate your schema and existing queries against a set of rules to prevent breaking changes',
690 | 'Integrates with GitHub as a part of your CI workflow',
691 | ].map(item => (
692 |
693 | {item}
694 |
695 | ))}
696 |
697 |
698 |
699 |
700 |
701 |
702 | {' '}
703 | Our schema validation integrates with GitHub so it's a natural part
704 | of your existing CI workflow. We hope to create even more natural
705 | extension points in your editor and beyond to optimize collaboration
706 | between frontend and backend engineers.
707 |
708 |
716 |
717 |
718 |
719 | Not only will backend engineers love our new schema collaboration
720 | features, they can also take advantage of schema monitoring from
721 | within Apollo Engine in order to determine which queries need
722 | optimization. Apollo Engine provides field by field monitoring for
723 | your entire schema that allows you to see how often a field is used
724 | and how much time it takes to resolve.
725 |
726 | Apollo Engine schema analysis
727 |
728 |
729 |
730 |
731 | Many teams have told us they want better tools for managing their
732 | schemas, so we're excited to see where this is heading in the next
733 | couple months. We see a sample workflow looking like this. If a
734 | frontend developer wants to add a field based on the needs of their
735 | UI, they can submit a pull request which alerts a backend engineer.
736 | THe backend engineer can use our GitHub checks integration to ensure
737 | that any schema changes are non-breaking. Then, they can use the
738 | schema validation report combined with Apollo Engine schema metrics
739 | to offer feedback on the change. We think this end to end workflow
740 | will not only improve productivity but also collaboration between
741 | both sides.
742 |
743 | Schema collaboration
744 |
745 |
746 |
747 |
748 | Another reason to use Apollo Server for your GraphQL layer is that
749 | you'll be soon able to run it on the edge. This is something
750 | experimental that we've been working on which is super cool. It uses
751 | Cloudflare's new worker platform to run Apollo Server in a truly
752 | serverless environment. This allows you to use the Data Source API
753 | to cache whole query responses from within your CDN and partial
754 | responses on the edge, delivering data to your users faster. If
755 | you'd like to be on the list for early access, check out the link
756 | below. We'd love to hear your feedback!
757 |
758 | GraphQL on the edge
759 |
760 |
761 |
762 | {[
763 | `Run Apollo Server on the edge using Cloudflare's new worker platform`,
764 | 'Cache whole query responses from within the CDN',
765 | 'Completely serverless',
766 | 'Early access: apollographql.com/edge',
767 | ].map((item, idx) => (
768 |
769 | {item}
770 |
771 | ))}
772 |
773 |
774 |
775 |
776 |
777 | With better visibility into our GraphQL APIs through a comprehensive
778 | tooling story and reducing the steps it takes to build and deploy a
779 | GraphQL layer into production, I think we'll be able to make both
780 | frontend and backend teams happy in the end. Between Data Sources,
781 | schema management, and running GraphQL on the edge, we're super
782 | excited with this new direction and would love to hear your thoughts
783 | on what the next generation of GraphQL servers could look like.
784 |
785 |
786 |
787 |
788 |
789 | Finally, if you're looking for information to take back to your
790 | team, definitely check out our new learning resource at
791 | apollographql.com/docs. It features implementation guides for auth,
792 | testing, schema design, state management as well as getting started
793 | guides for Apollo Server 2.0 and Apollo Client.
794 |
795 |
800 | Get started!
801 |
802 |
803 | apollographql.com/docs
804 |
805 |
806 |
807 |
808 | If you have any questions, feel free to come find me or any members
809 | of the Apollo team later today. Thank you!
810 |
811 |