GraphQL language text asking for exact data needs Exact data response (for example, in JSON) Transport channel (for example, HTTPS) API serviceAPI consumer GraphQL runtime
(This page has no text content)
GraphQL in Action SAMER BUNA M A N N I N G SHELTER ISLAND
For online information and ordering of this and other Manning books, please visit www.manning.com. The publisher offers discounts on this book when ordered in quantity. For more information, please contact Special Sales Department Manning Publications Co. 20 Baldwin Road PO Box 761 Shelter Island, NY 11964 Email: orders@manning.com ©2021 by Manning Publications Co. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by means electronic, mechanical, photocopying, or otherwise, without prior written permission of the publisher. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in the book, and Manning Publications was aware of a trademark claim, the designations have been printed in initial caps or all caps. Recognizing the importance of preserving what has been written, it is Manning’s policy to have the books we publish printed on acid-free paper, and we exert our best efforts to that end. Recognizing also our responsibility to conserve the resources of our planet, Manning books are printed on paper that is at least 15 percent recycled and processed without the use of elemental chlorine. Manning Publications Co. Development editor: Karen Miller 20 Baldwin Road Technical development editor: Alain Couniot PO Box 761 Review editor: Aleksandar Dragosavljević Shelter Island, NY 11964 Production editor: Deirdre Hiam Copy editor: Tiffany Taylor Proofreader: Katie Tennant Technical proofreader: Valentin Crettaz Typesetter: Gordan Salinovic Cover designer: Marija Tudor ISBN 9781617295683 Printed in the United States of America
To my wife, Chalena, for all your unconditional, loving support To my children, Odin, Ally, and Leo, for inspiring me each and every day To my parents, Nemeh and Sharif, for teaching me the value of hard work and always pushing me to the limit
(This page has no text content)
vii brief contents PART 1 EXPLORING GRAPHQL .....................................................1 1 ■ Introduction to GraphQL 3 2 ■ Exploring GraphQL APIs 30 3 ■ Customizing and organizing GraphQL operations 47 PART 2 BUILDING GRAPHQL APIS..............................................75 4 ■ Designing a GraphQL schema 77 5 ■ Implementing schema resolvers 110 6 ■ Working with database models and relations 138 7 ■ Optimizing data fetching 171 8 ■ Implementing mutations 208 PART 3 USING GRAPHQL APIS ................................................251 9 ■ Using GraphQL APIs without a client library 253 10 ■ Using GraphQL APIs with Apollo client 293
(This page has no text content)
ix contents preface xv acknowledgments xvii about this book xix about the author xxii about the cover illustration xxiii PART 1 EXPLORING GRAPHQL............................................1 1 Introduction to GraphQL 3 1.1 What is GraphQL? 4 The big picture 5 ■ GraphQL is a specification 9 ■ GraphQL is a language 9 ■ GraphQL is a service 11 1.2 Why GraphQL? 14 What about REST APIs? 17 ■ The GraphQL way 18 ■ REST APIs and GraphQL APIs in action 20 1.3 GraphQL problems 25 Security 25 ■ Caching and optimizing 26 ■ Learning curve 28 2 Exploring GraphQL APIs 30 2.1 The GraphiQL editor 31
CONTENTSx 2.2 The basics of the GraphQL language 36 Requests 36 ■ Fields 39 2.3 Examples from the GitHub API 41 Reading data from GitHub 41 ■ Updating data at GitHub 43 Introspective queries 44 3 Customizing and organizing GraphQL operations 47 3.1 Customizing fields with arguments 48 Identifying a single record to return 48 ■ Limiting the number of records returned by a list field 49 ■ Ordering records returned by a list field 51 ■ Paginating through a list of records 51 Searching and filtering 53 ■ Providing input for mutations 54 3.2 Renaming fields with aliases 55 3.3 Customizing responses with directives 57 Variables and input values 58 ■ The @include directive 61 The @skip directive 62 ■ The @deprecated directive 63 3.4 GraphQL fragments 63 Why fragments? 63 ■ Defining and using fragments 64 Fragments and DRY 65 ■ Fragments and UI components 66 Inline fragments for interfaces and unions 71 PART 2 BUILDING GRAPHQL APIS....................................75 4 Designing a GraphQL schema 77 4.1 Why AZdev? 77 4.2 The API requirements for AZdev 78 The core types 80 4.3 Queries 82 Listing the latest Task records 82 ■ Search and the union/interface types 84 ■ Using an interface type 87 ■ The page for one Task record 88 ■ Entity relationships 90 ■ The ENUM type 91 List of scalar values 92 ■ The page for a user’s Task records 92 Authentication and authorization 93 4.4 Mutations 94 Mutation input 96 ■ Deleting a user record 98 ■ Creating a Task object 99 ■ Creating and voting on Approach entries 100 4.5 Subscriptions 102 4.6 Full schema text 103
CONTENTS xi 4.7 Designing database models 103 The User model 104 ■ The Task/Approach models 105 The Approach Details model 107 5 Implementing schema resolvers 110 5.1 Running the development environment 110 Node.js packages 113 ■ Environment variables 113 5.2 Setting up the GraphQL runtime 113 Creating the schema object 115 ■ Creating resolver functions 116 ■ Executing requests 117 5.3 Communicating over HTTP 119 5.4 Building a schema using constructor objects 122 The Query type 123 ■ Field arguments 125 ■ Custom object types 127 ■ Custom errors 129 5.5 Generating SDL text from object-based schemas 132 The schema language versus the object-based method 134 5.6 Working with asynchronous functions 135 6 Working with database models and relations 138 6.1 Running and connecting to databases 139 6.2 The taskMainList query 141 Defining object types 142 ■ The context object 143 Transforming field names 147 ■ Transforming field values 150 Separating interactions with PostgreSQL 152 6.3 Error reporting 154 6.4 Resolving relations 156 Resolving a one-to-one relation 157 ■ Resolving a one-to-many relation 166 7 Optimizing data fetching 171 7.1 Caching and batching 172 The batch-loading function 175 ■ Defining and using a DataLoader instance 177 ■ The loader for the approachList field 179 7.2 Single resource fields 182 7.3 Circular dependencies in GraphQL types 187 Deeply nested field attacks 188
CONTENTSxii 7.4 Using DataLoader with custom IDs for caching 190 The taskMainList field 190 ■ The search field 193 7.5 Using DataLoader with MongoDB 199 8 Implementing mutations 208 8.1 The mutators context object 209 8.2 The Mutation type 211 8.3 User mutations 211 The userCreate mutation 211 ■ The userLogin mutation 217 8.4 Authenticating API consumers 221 The me root query field 226 8.5 Mutations for the Task model 232 8.6 Mutations for the Approach model 235 The approachCreate mutation 236 ■ The approachVote mutation 244 8.7 The userDelete mutation 246 PART 3 USING GRAPHQL APIS ......................................251 9 Using GraphQL APIs without a client library 253 9.1 Using a web UI library 254 9.2 Running the web server 255 9.3 Making Ajax requests 258 9.4 Performing GraphQL query requests 260 Using GraphQL fragments in UI components 263 ■ Including variables in requests 265 9.5 Performing GraphQL mutation requests 269 The login/signup forms 269 ■ Handling generic server errors 273 ■ Authenticating GraphQL requests 277 ■ The Create Task form 278 ■ The Create Approach form 281 Voting on an Approach 286 9.6 Performing query requests scoped for a user 287 The Search form 289 9.7 Next up 291
CONTENTS xiii 10 Using GraphQL APIs with Apollo client 293 10.1 Using Apollo Client with JavaScript 294 Making a query request 295 ■ Making a mutation request 300 10.2 Using Apollo Client with React 303 Using the query and mutate methods directly 303 ■ Including authentication headers 306 ■ Using Apollo hook functions 309 Using the automatic cache 316 ■ Manually updating the cache 317 ■ Performing operations conditionally 321 10.3 Managing local app state 326 10.4 Implementing and using GraphQL subscriptions 332 Polling and refetching 332 ■ Implementing subscriptions 334 Apollo Server 340 ■ Using subscriptions in UIs 342 Wrapping up 345 index 347
(This page has no text content)
xv preface GraphQL is a game changer. It immediately grabbed my full attention when I first heard about it back in 2015, when Facebook first announced the project. I’ve been a frustrated maintainer and user of multiple REST-ish APIs, and hearing how Facebook engineers were trying to solve common data API problems with this new GraphQL language was a clear sign for me to learn about it. GraphQL has many advantages and disadvantages. It solves many technical prob- lems beautifully; but the best thing about it, in my opinion, is that it greatly improves the communication process between frontend clients and backend services. Not only does GraphQL make communication a lot more efficient for both sides, but it also gives them both a rich, declarative language. GraphQL services can use that language to express what data they can provide, and GraphQL clients can use the language to express what data they need. GraphQL also enables frontend developers to be inde- pendent of backend developers, and that in itself is a big deal. Frontend developers get more freedom and a stronger impact on the features of the data APIs they use. GraphQL is programming-language agnostic. You can create GraphQL services in JavaScript, Java, Ruby, Python, C#, PHP, Go, and many other languages. However, I had to pick a programming language for the project we’re building in this book. I chose JavaScript because it is the most popular programming language out there. This does mean you need to be familiar with JavaScript to get the best value out of this book, including modern JavaScript (ECMAScript 2015+) and the Node.js runtime. The book’s project also uses the React JavaScript library in chapters 9 and 10, but all the React code is provided and explained where needed.
PREFACExvi There is no shortage of learning resources for GraphQL, but what I noticed while learning it is a scarcity of practical, non-abstract materials. That is why I designed this book to be a practical reference for working with a full-stack GraphQL-based project. This book took me a long time to produce. I researched and developed the ideal flow for learning the many concepts covered in the book. I also provide many resources to make your learning experience as smooth as possible. The book features a GitHub repository, and progress milestones throughout the book have Git branches that you can check out. I hope this will help you better follow the code and allow you to restart at any point. Learning GraphQL was one of the best time investments I have ever made. GraphQL allows me to implement ideas faster, and it makes my projects perform bet- ter. Working with GraphQL is simply a more pleasant experience overall. I hope this book will enable you to make that investment and join in on all the joy we GraphQL lovers are having in the GraphQL ecosystem of excellence.
xvii acknowledgments This book would not have been possible without the excellent contributions of many people. I’m privileged to have those people in my life, and I profoundly appreciate them for helping me produce the best possible version of this book. Huge thanks go to the Manning team for their patience and guidance throughout the writing of this book. Special thanks go to Karen Miller, my developmental editor, and Tiffany Taylor, my copyeditor, who both taught me a great deal about efficient and clear writing. I would also like to thank Deirdre Hiam, my project editor; Katie Tennant, my proofreader; and Aleksandar Dragosavljevic, my reviewing editor. I’m grateful for all their tireless work to improve the language and presentations of the book. Writing for Manning was one of the best book-writing experiences I have ever had. Many awesome software developers read drafts of this book and gave me valuable feedback about how to improve things. I am grateful for all of you, especially my tech- nical reviewer, Valentin Crettaz, who found problems in the draft that I would have never found with my biased eyes. I’d like to also thank my friends Kyle Holden and Ray- mond Ly, and my wife, Chalena, for proofreading the language of the book and help- ing me fine-tune the grammar and phrasing to better communicate my thoughts. I’d like to also thank my mentors in the GraphQL ecosystem, from whom I learned a lot. They inspired me, encouraged me, and kept me in check throughout the process of getting this book out. Special thanks go to Lee Byron for answering many of my ques- tions and making sure the topics and flow of this book are as useful as they can be. To all of the reviewers—Adam Wendell Åslund, Andrew Eleneski, Andy Kirsch, Dary Merckens, Dave Cutler, Enric Cecilla, Ethien Daniel, Salinas Dominguez, Ian
ACKNOWLEDGMENTSxviii Lovell, Isaac Wong, James Black, Jason Down, Jeremy Lange, John Guthrie, Jonathan Twaddell, Kelvin D. Meeks, Krzysztof Kamyczek, Louis Aloia, Philip Patterson, Rich Cook, Richard Tobias, Ronald Borman, Russel Dawn Cajoles, and Wayne Mather— your suggestions helped to make this a better book. Thank you, everyone. You are all amazing, and your work made this book a thousand times better.
Comments 0
Loading comments...
Reply to Comment
Edit Comment