restful web apis


Praise for RESTful Web APIs “This book is the best place to start learning the essential craft of API Design.” —Matt McLarty Cofounder, API Academy “The entire time I read this book, I was cursing. I was cursing because as I read each explanation, I was worried that they were so good that it would be hard to find a better one to use in my own writing. You will not find another work that explores the topic so thoroughly yet explains the topic so clearly. Please, take these tools, build something fantastic, and share it with the rest of the world, okay?” —Steve Klabnik Author, Designing Hypermedia APIs “Wonderfully thorough treatment of hypermedia formats, REST’s least well understood tenet." —Stefan Tilkov REST evangelist, author, and consultant “The best practical guide to hypermedia APIs. A must-have.” — Ruben Verborgh Semantic hypermedia researcher Leonard Richardson and Mike Amundsen Foreword by Sam Ruby RESTful Web APIs RESTful Web APIs by Leonard Richardson and Mike Amundsen with a Foreword by Sam Ruby Copyright © 2013 Leonard Richardson, amundsen.com, Inc., and Sam Ruby. All rights reserved. Printed in the United States of America. Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472. O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://my.safaribooksonline.com). For more information, contact our corporate/ institutional sales department: 800-998-9938 or corporate@oreilly.com. Editors: Simon St. Laurent and Meghan Blanchette Production Editor: Christopher Hearse Copyeditor: Jasmine Kwityn Proofreader: Linley Dolby Indexer: Judith McConville Cover Designer: Randy Comer Interior Designer: David Futato Illustrator: Rebecca Demarest September 2013: First Edition Revision History for the First Edition: 2013-09-10: First release See http://oreilly.com/catalog/errata.csp?isbn=9781449358068 for release details. Nutshell Handbook, the Nutshell Handbook logo, and the O’Reilly logo are registered trademarks of O’Reilly Media, Inc. RESTful Web APIs, the image of Hoffmann’s two-toed sloth, and related trade dress are trade‐ marks of O’Reilly Media, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O’Reilly Media, Inc., was aware of a trade‐ mark claim, the designations have been printed in caps or initial caps. While every precaution has been taken in the preparation of this book, the publisher and authors assume no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein. ISBN: 978-1-449-35806-8 [LSI] For Sienna, Dalton, and Maggie. —Leonard For Milo “The Supervisor,” my constant and patient companion throughout this and so many other projects. Thanks, buddy! —Mike Table of Contents Foreword. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv 1. Surfing the Web. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Episode 1: The Billboard 2 Resources and Representations 2 Addressability 3 Episode 2: The Home Page 3 Short Sessions 4 Self-Descriptive Messages 5 Episode 3: The Link 6 Standardized Methods 8 Episode 4: The Form and the Redirect 9 Application State 10 Resource State 11 Connectedness 13 The Web Is Something Special 14 Web APIs Lag Behind the Web 15 The Semantic Challenge 16 2. A Simple API. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 HTTP GET: Your Safe Bet 18 How to Read an HTTP Response 18 JSON 20 Collection+JSON 21 Writing to an API 22 HTTP POST: How Resources Are Born 24 Liberated by Constraints 25 v Application Semantics Create the Semantic Gap 27 3. Resources and Representations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 A Resource Can Be Anything 30 A Representation Describes Resource State 30 Representations Are Transferred Back and Forth 31 Resources with Many Representations 32 The Protocol Semantics of HTTP 33 GET 34 DELETE 35 Idempotence 36 POST-to-Append 37 PUT 37 PATCH 38 LINK and UNLINK 39 HEAD 40 OPTIONS 40 Overloaded POST 41 Which Methods Should You Use? 42 4. Hypermedia. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 HTML as a Hypermedia Format 46 URI Templates 49 URI Versus URL 50 The Link Header 51 What Hypermedia Is For 52 Guiding the Request 52 Promises About the Response 53 Workflow Control 54 Beware of Fake Hypermedia! 55 The Semantic Challenge: How Are We Doing? 56 5. Domain-Specific Designs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 Maze+XML: A Domain-Specific Design 60 How Maze+XML Works 61 Link Relations 62 Follow a Link to Change Application State 64 The Collection of Mazes 65 Is Maze+XML an API? 67 Client #1: The Game 68 A Maze+XML Server 72 Client #2: The Mapmaker 74 vi | Table of Contents Client #3: The Boaster 76 Clients Do the Job They Want to Do 77 Extending a Standard 77 The Mapmaker’s Flaw 80 The Fix (and the Flaw in the Fix) 81 Maze as Metaphor 83 Meeting the Semantic Challenge 83 Where Are the Domain-Specific Designs? 83 The Prize at the End 84 Hypermedia in the Headers 84 Steal the Application Semantics 84 If You Can’t Find a Domain-Specific Design, Don’t Make One 86 Kinds of API Clients 86 Human-Driven Clients 86 Automated Clients 87 6. The Collection Pattern. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 What’s a Collection? 93 Collections Link to Items 93 Collection+JSON 94 Representing the Items 95 The Write Template 98 Search Templates 99 How a (Generic) Collection Works 100 GET 100 POST-to-Append 100 PUT and PATCH 101 DELETE 101 Pagination 101 Search Forms 102 The Atom Publishing Protocol (AtomPub) 102 AtomPub Plug-in Standards 104 Why Doesn’t Everyone Use AtomPub? 105 The Semantic Challenge: How Are We Doing? 106 7. Pure-Hypermedia Designs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 Why HTML? 109 HTML’s Capabilities 110 Hypermedia Controls 110 Plug-in Application Semantics 111 Microformats 113 The hMaze Microformat 114 Table of Contents | vii Microdata 116 Changing Resource State 117 Adding Application Semantics to Forms 119 The Alternative to Hypermedia Is Media 122 HTML’s Limits 124 HTML 5 to the Rescue? 124 The Hypertext Application Language 125 Siren 129 The Semantic Challenge: How Are We Doing? 130 8. Profiles. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 How Does A Client Find the Documentation? 134 What’s a Profile? 135 Linking to a Profile 135 The profile Link Relation 135 The profile Media Type Parameter 136 Special-Purpose Hypermedia Controls 136 Profiles Describe Protocol Semantics 137 Profiles Describe Application Semantics 138 Link Relations 138 Unsafe Link Relations 139 Semantic Descriptors 140 XMDP: The First Machine-Readable Profile Format 141 ALPS 143 Advantages of ALPS 148 ALPS Doesn’t Do Everything 150 JSON-LD 150 Embedded Documentation 154 In Summary 155 9. The Design Procedure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 Two-Step Design Procedure 157 Seven-Step Design Procedure 158 Step 1: List the Semantic Descriptors 159 Step 2: Draw a State Diagram 161 Step 3: Reconcile Names 164 Step 4: Choose a Media Type 167 Step 5: Write a Profile 169 Step 6: Implementation 169 Step 7: Publication 170 Example: You Type It, We Post It 173 List the Semantic Descriptors 173 viii | Table of Contents Draw a State Diagram 174 Reconcile Names 174 Choose a Media Type 175 Write a Profile 176 Some Design Advice 177 Resources Are Implementation Details 178 Don’t Fall into the Collection Trap 178 Don’t Start with the Representation Format 179 URL Design Doesn’t Matter 180 Standard Names Are Probably Better Than Your Names 182 If You Design a Media Type 183 When Your API Changes 185 Don’t Keep All the Hypermedia in One Place 189 Adding Hypermedia to an Existing API 190 Fixing Up an XML-Based API 191 Is It Worth It? 192 Alice’s Second Adventure 192 Episode 1: The Nonsense Representation 192 Episode 2: The Profile 194 Alice Figured It Out 196 10. The Hypermedia Zoo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 Domain-Specific Formats 200 Maze+XML 200 OpenSearch 201 Problem Detail Documents 201 SVG 202 VoiceXML 204 Collection Pattern Formats 206 Collection+JSON 206 The Atom Publishing Protocol 207 OData 208 Pure Hypermedia Formats 215 HTML 215 HAL 216 Siren 217 The Link Header 218 The Location and Content-Location Headers 218 URL Lists 219 JSON Home Documents 219 The Link-Template Header 220 WADL 221 Table of Contents | ix XLink 222 XForms 223 GeoJSON: A Troubled Type 224 GeoJSON Has No Generic Hypermedia Controls 226 GeoJSON Has No Media Type 228 Learning from GeoJSON 229 The Semantic Zoo 230 The IANA Registry of Link Relations 230 The Microformats Wiki 230 Link Relations from the Microformats Wiki 232 schema.org 233 Dublin Core 234 Activity Streams 234 The ALPS Registry 235 11. HTTP for APIs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 The New HTTP/1.1 Specification 238 Response Codes 238 Headers 238 Choosing Between Representations 239 Content Negotiation 239 Hypermedia Menus 240 The Canonical URL 241 HTTP Performance 241 Caching 241 Conditional GET 242 Look-Before-You-Leap Requests 244 Compression 245 Partial GET 246 Pipelining 247 Avoiding the Lost Update Problem 248 Authentication 249 The WWW-Authenticate and Authorization Headers 250 Basic Auth 251 OAuth 1.0 252 Where OAuth 1.0 Falls Short 255 OAuth 2.0 256 When to Give Up on OAuth 256 Extensions to HTTP 257 The PATCH Method 257 The LINK and UNLINK Methods 258 WebDAV 259 x | Table of Contents HTTP 2.0 260 12. Resource Description and Linked Data. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 RDF 264 RDF Treats URLs as URIs 265 When to Use the Description Strategy 266 Resource Types 269 RDF Schema 270 The Linked Data Movement 272 JSON-LD 274 JSON-LD as a Representation Format 275 Hydra 276 The XRD Family 280 XRD and JRD 281 Web Host Metadata Documents 282 WebFinger 283 The Ontology Zoo 284 schema.org RDF 284 FOAF 285 vocab.org 285 Conclusion: The Description Strategy Lives! 286 13. CoAP: REST for Embedded Systems. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 A CoAP Request 288 A CoAP Response 288 Kinds of Messages 289 Delayed Response 290 Multicast Messages 291 The CoRE Link Format 291 Conclusion: REST Without HTTP 293 A. The Status Codex. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295 B. The Header Codex. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 C. An API Designer’s Guide to the Fielding Dissertation. . . . . . . . . . . . . . . . . . . . . . . . . . . . 341 Glossary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357 Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361 Table of Contents | xi Foreword Progressive Disclosure is a concept in User Interface Design which advocates only pre‐ senting to the user the information they need when they need it. In many ways, the book you are reading right now is an example of this principle. In fact, it is quite likely that this book wouldn’t have “worked” a mere seven years ago. For you see, the programming world was quite a different place when RESTful Web Services, the predecessor of this book, was written. At that time, the term “REST” was was rarely used. And when it was used it was often misapplied, and widely misunder‐ stood. This was the case despite the fact that the standards upon which REST is based, namely HTTP and HTML, were developed and became IETF and W3C standards in roughly their current form in the second half of the 1990s. Roy Fielding’s thesis paper in which he introduced the term REST and on which this book was based was itself published in 2000. Leonard Richardson and I set out to correct this injustice. To do this, we focused pri‐ marily on the concepts underpinning HTTP, and we provided practical guidance on how to apply those concepts to applications. I’d like to think that we helped kick a few pebbles loose that started the avalanche of support for REST that came forth since that time. REST rapidly took on a life of its own, and in the process has become a buzzword. In fact it now is pretty much the case that presenting a web interface and calling it REST is practically the default. We’ve definitely come a long way in a few short years. Admittedly, REST as a term is often over applied, and not always correctly. But all things considered, I am very pleased that the concepts of resources and URIs have successfully managed to infiltrate their way into application interface design. The web, after all, is a resilient place, and these new interfaces, albeit imperfect, are leaps and bounds better than the ones that they replace. But we can do better. xiii Now that those building blocks are in place, it is time to take a step back, survey the territory, and build on top of these concepts. The next logical step is to explore media types in general, and hypermedia formats in specific. While the first book focused almost exclusively on the correct application of HTTP, it is time to delve more deeply into the concepts behind hypertext media types like HTML—media types that aren’t tightly bound to a single application or even a single vendor. HTML remains a prime example of a such a hypermedia format, and it continues to hold a special place in web architecture. In fact, my personal journey of discovery has been to take a deep dive into development of the W3C standard for HTML, now branded as HTML5. And while HTML does have a prominent place in this new book, there is so much more to cover on the topic of hypermedia. So while I have remained in touch, Leonard picked up a capable replacement for my role as coauthor in Mike Amundsen. It has been a pleasure to watch this book be written, and in reading this book I’ve learned about a number of media types that I had not been exposed to by any other source. More importantly, this book shows what these types have in common, and how to differentiate them, as each has its own specialty. Hopefully the pebbles that this book kicks loose will have the same effect as its prede‐ cessor did. Who knows, perhaps in another seven years it will be time to do this all over again, and highlight some other facet of Representational State Transfer that continues to be under-appreciated. —Sam Ruby xiv | Foreword Introduction “Most software systems are created with the implicit assumption that the entire system is under the control of one entity, or at least that all entities participating within a system are acting towards a common goal and not at cross-purposes. Such an assumption cannot be safely made when the system runs openly on the Internet.” — Roy Fielding Architectural Styles and the Design of Network-based Software Architectures “A Discordian Shall Always use the Official Discordian Document Numbering System.” — Malaclypse the Younger and Lord Omar Khayyam Ravenhurst Principia Discordia I’m going to show you a better way to do distributed computing, using the ideas un‐ derlying the most successful distributed system in history: the World Wide Web. I hope you’ll read this book if you’ve decided (or your manager has decided) that your company needs to publish a web API. It doesn’t matter whether you’re planning a public API, a purely internal API, or an API accessible by trusted partners—they can all benefit from the philosophy of REST. This is not necessarily the book for you if you want to learn how to write API clients. That’s because most existing API designs are based on assumptions that are several years old, assumptions that I’d like to destroy. Most of today’s APIs have a big problem: once deployed, they can’t change. There are big-name APIs that stay static for years at a time, as the industry changes around them, because changing them would be too difficult. But RESTful architectures are designed for managing change. The World Wide Web is made of millions of websites, running atop thousands of different server implementa‐ tions, and undergoing periodic redesigns. Websites are accessed by billions of users who are using hundreds of different client implementations on dozens of hardware plat‐ xv forms. Your deployment won’t look like this howling mess, but the closer you come to web scale, the more familiar this picture will look. A very simple system is always easy to change. At small scales, a RESTful system has a larger up-front design cost than a push-button solution. But as your API matures and starts to change, you’ll really need some way—like REST—of adapting to change. • An API that’s commercially successful will stay available for years on end. Some APIs have hundreds or even thousands of users. Even if the problem domain only changes occasionally, the cumulative effect on clients can be huge. • Some APIs change all the time, with new data elements and business rules con‐ stantly being added. • In some APIs, each client can change the workflow to suit its needs. Even if the API itself never changes, each client will experience it differently. • The people who write the API clients usually don’t work on the same team as the people who write the servers. All APIs that are open to the public fall under this category. If you don’t know what kind of clients are out there, you need to be very careful about making changes—or you need to have a design that can change without breaking all the clients. If you copy existing designs for your API, you will probably only repeat the mistakes of the past. Unfortunately, most of the improvements are happening below the surface, in experiments and through slow-moving standards processes. I’ll cover dozens of specific technologies in this book, including many that are still under development. But my main goal is to teach you the underlying principles of REST. Learn those, and you’ll be able to exploit whichever experiments pan out and whichever standards are approved. There are two specific problems I’m trying to solve with this book: duplication of effort and avoidance of hypermedia. Let’s take a look at them. Duplication of Effort An API released today will be named after the company that hosts it. We talk about the “Twitter API,” the “Facebook API,” and the “Google+ API.” These three APIs do similar things. They all have some notion of user accounts and (among other things) they all let users post a little bit of text to their accounts. But each API has a completely different design. Learning one API doesn’t help you learn the next one. Of course, Twitter, Facebook, and Google are big companies that compete with each other. They don’t want to make it easy for you to learn their competitors’ APIs. But small companies and nonprofits do the same thing. They design their APIs as though nobody else had ever had a similar idea. This interferes with their goal of getting people to actually use their APIs. xvi | Introduction 1. The full list of ProgrammableWeb APIs tagged with microblogging provides information about each of these APIs. 2. RESTful Web Services is now freely available as part of O’Reilly’s Open Books Project. You can download a PDF copy of the book from the book’s page. 3. If you’re wondering, this is why we changed the title. The term “web services” became so tightly coupled with SOAP that when SOAP went down, it took “web services” with it. These days, everyone talks about APIs instead. Let me show you just one example. The website ProgrammableWeb has a directory of over 8,000 APIs. As I write this, it knows about 57 microblogging APIs—APIs whose main purpose is posting a little bit of text to a user account.1 It’s great that there are 57 companies publishing APIs in this field, but do we really need 57 different designs? We’re not talking about something complicated here, like insurance policies or regulatory compliance. We’re talking about posting a little bit of text to a user account. Do you want to be the one who designs the 58th microblogging API? The obvious solution would be to create a standard for microblogging APIs. But there already is a standard that would work just fine: the Atom Publishing Protocol. It was published in 2005, and almost nobody uses it. There’s something about APIs that makes everyone want to design their own from scratch, even when that makes no sense from a business perspective. I don’t think I can single-handledly stop this wasted effort, but I do think I can break down the problem into parts that make sense, and present some ways for a new API to reuse work that’s already been done. Hypermedia Is Hard Back in 2007, Leonard Richardson and Sam Ruby wrote the predecessor to this book, RESTful Web Services (O’Reilly). That book also tried to address two big problems. One of the problems has been solved; the other is nowhere close to being solved.2 The first problem: in 2007, the REST school of API design was engaged in a standoff against a rival school that used heavyweight technologies based on SOAP and ques‐ tioned the very legitimacy of the REST school. RESTful Web Services was a salvo in this standoff, a defense of RESTful design principles against the attacks of the SOAP school. Well, the standoff is over, and REST won. SOAP APIs are still used, but only within the big companies that were backing the SOAP school in the first place. Pretty much all new public-facing APIs pay lip service to RESTful principles.3 Which brings me to the second problem: REST isn’t just a technical term—it’s also a marketing buzzword. For a long time, REST was a slogan that signified nothing beyond opposition to the SOAP school. Any API that didn’t use SOAP was marketed as REST, Introduction | xvii even if its design made no sense or betrayed the technical principles of REST. This was inaccurate, confusing, and it gave REST—i.e., REST as a technical term—a bad name. This situation has improved a lot since 2007. When I look at new APIs, I see the work of developers who understand the concepts I’ll be explaining in the first few chapters of this book. Most developers who fly the REST flag today understand resources and representations, how to name resources with URLs, and how to properly use HTTP methods. The first three chapters of this book don’t do much but get new developers up to speed. But there’s one aspect of REST that most developers still don’t understand: hypermedia. We all understand hypermedia in the context of the Web. It’s just a fancy word for links. Web pages link to each other, and the result is the World Wide Web, driven by hyper‐ media. But it seems we’ve got a mental block when it comes to hypermedia in web APIs. This is a big problem, because hypermedia is the feature that makes a web API capable of handling changes gracefully. Starting in Chapter 4, my overriding goal for RESTful Web APIs will be to teach you how hypermedia works. If you’ve never heard of this term, I’ll teach it to you along with the other important REST concepts. If you’ve heard of hypermedia but the concept intimidates you, I’ll do what I can to build up your courage. If you just haven’t been able to wrap your head around hypermedia, I’ll show it to you in every way I can think of, until you get it. RESTful Web Services covered hypermedia, but it wasn’t central to the book. It was possible to skip the hypermedia parts of the book and still design a functioning API. By contrast, RESTful Web APIs is effectively a book about hypermedia. I did it this way because hypermedia is the single most important aspect of REST, and the least understood. Until we all understand hypermedia, REST will continue to be viewed as a marketing buzzword rather than a serious attempt to handle the complexity of distributed computing. What’s in This Book? The first four chapters introduce the concepts behind REST, as it applies to web APIs. Chapter 1, Surfing the Web This chapter explains basic terminology using a RESTful system you’re already fa‐ miliar with: a website. Chapter 2, A Simple API This chapter translates the lessons of the Web to a programmable API with identical functionality to the website discussed in Chapter 1. xviii | Introduction Chapter 3, Resources and Representations Resources are the fundamental concept underlying HTTP, and representations are the fundamental concept underlying REST. This chapter explains how they’re re‐ lated. Chapter 4, Hypermedia Hypermedia is the missing ingredient that ties representations together into a co‐ herent API. This chapter shows what hypermedia is capable of, mostly using a hypermedia data format you’re already familiar with: HTML. The next four chapters describe different strategies for designing a hypermedia API: Chapter 5, Domain-Specific Designs The obvious strategy is to design a completely new standard that deals with your exact problem. I use the Maze+XML standard as an example. Chapter 6, The Collection Pattern One pattern in particular—the collection pattern—shows up over and over again in API design. In this chapter, I show off two different standards that capture this pattern: Collection+JSON and AtomPub. Chapter 7, Pure-Hypermedia Designs When the collection pattern doesn’t fit your requirements, you can convey any representation you want using a general-purpose hypermedia format. This chapter shows how it works using three general hypermedia formats (HTML, HAL, and Siren) as examples. This chapter also introduces HTML microformats and micro‐ data, which lead in to the next chapter. Chapter 8, Profiles A profile fills in the gaps between a data format (which can be used by many different APIs) and a specific API implementation. The profile format I recommend is ALPS, but I also cover XMDP and JSON-LD. In this chapter, my advice begins to outstrip the state of the art at the time this book was written. I had to develop the ALPS format for this book, because nothing else would do the job. If you’re already familiar with hypermedia-based designs, you might be able to skip up to Chapter 8, but I don’t think you should skip past it. Chapters 9 through 13 cover practical topics like choosing the right hypermedia format and getting the most out of the HTTP protocol. Chapter 9, The Design Procedure This chapter brings together everything discussed in the book so far, and gives a step-by-step guide to designing a RESTful API. Introduction | xix Chapter 10, The Hypermedia Zoo In an attempt to show what hypermedia is capable of, this chapter discusses about 20 standardized hypermedia data formats, most of them not covered elsewhere in the book. Chapter 11, HTTP for APIs This chapter gives some best practices for the use of HTTP in API implementations. I also discuss some extensions to HTTP, including the forthcoming HTTP 2.0 pro‐ tocol. Chapter 12, Resource Description and Linked Data Linked Data is the Semantic Web community’s approach to REST. JSON-LD is arguably the most important Linked Data standard. It’s covered briefly in Chap‐ ter 8, and I revisit it here. This chapter also covers the RDF data model, and some RDF-based hypermedia formats that I didn’t get to in Chapter 10. Chapter 13, CoAP: REST for Embedded Systems This chapter closes out the core body of the book by covering CoAP, a RESTful protocol that doesn’t use HTTP at all. Appendix A, The Status Codex An extension of Chapter 11, this appendix provides an in-depth look at the 41 standard status codes defined in the HTTP specification, as well as a few useful codes defined as extensions. Appendix B, The Header Codex Similar to Appendix A, this appendix is also an extension of Chapter 11. It provides a detailed outline of the 46 request and response headers defined in the HTTP specification, as well as a few extensions. Appendix C, An API Designer’s Guide to the Fielding Dissertation This appendix includes an in-depth discussion of the foundational document of REST, in terms of what it means for API design. Glossary The glossary contains definitions to terms you’ll frequently encounter when work‐ ing with RESTful web APIs. It’s a good place to turn for familiarizing yourself with basic concepts or if you need a quick, at-a-glance reminder of a particular concept’s definition. What’s Not in This Book RESTful Web Services was the first book-length treatment of REST, and it had to cover a lot of ground. Fortunately, there are now over a dozen books on various aspects of REST, and that frees up RESTful Web APIs to focus on the core concepts. xx | Introduction To keep this book focused, I’ve removed a few topics that you might have been expecting me to cover. I want to tell you what is not in this book, so that you don’t buy it and then feel disappointed: • Client programming is not covered here. Writing a client to consume a hypermedia- based API is a new kind of challenge. Right now, the closest thing we have to a generic API client is a library that sends HTTP requests. This was true in 2007, and it’s still true. The problem is on the server side. When you write a client for an existing API, you’re at the mercy of the API designer. I can’t give you any general advice, because right now there’s no consistency across APIs. That’s why, in this book, I’m trying to drum up enthusiasm for a little server- side consistency. When APIs become more similar to each other, we’ll be able to write more sophisticated client-side tools. Chapter 5 contains some sample client implementations and tries to classify dif‐ ferent types of clients, but if you want a whole book on API clients, this is not your book. I don’t think the book you want exists right now. • The most widely deployed API client in the world is JavaScript’s XMLHttpRequest library. There’s a copy in every web browser, and most websites today are built atop APIs designed for consumption by XMLHttpRequest. But that’s far too big a field to cover properly in this book. There are whole books written about individual JavaScript libraries. • I spend quite a bit of time on the mechanics of HTTP (Chapter 11, Appendix A, and Appendix B), but I don’t cover any given HTTP topic in a lot of depth, and there are some topics—notably HTTP intermediaries like caches and proxies— which I barely cover at all. • RESTful Web Services focused heavily on breaking down your business require‐ ments into a set of interlinked resources. My experience since 2007 has convinced me that thinking of API design as resource design is a very effective way to avoid thinking about hypermedia. This book takes a different approach, focusing on rep‐ resentations and state transitions rather than resources. That said, the resource design approach is certainly valid. For advice on moving in that direction, I recommend RESTful Web Services Cookbook by Subbu Allamaraju (O’Reilly). Administrative Notes This book has two authors (Leonard and Mike), but for the duration of this book we’ve merged our identities into a single authorial “I.” Introduction | xxi 4. The meaning of “SHOULD” is given in RFC 2119. Nothing in this book is tied to any particular programming language. All of the code takes the form of messages (usually JSON or XML documents) sent over a network protocol (usually HTTP). I will be assuming that you’re familiar with common pro‐ gramming concepts like antipatterns and breadth-first search, and that you have a basic understanding of how the World Wide Web works. I won’t be presenting it, but there is real code behind the servers and clients I talk about in Chapter 1, Chapter 2, and Chapter 5. You can get that code from the RESTful Web APIs GitHub repository, or from the official website, and run it yourself. These clients and servers are written in JavaScript, using the Node library. I chose Node because it lets me use the same programming language for client and server code. You won’t need to mentally switch back and forth between programming lan‐ gauges to understand both sides of a client-server transaction. Node is open source and available on Windows, Mac, and Linux systems. It is easy to install on these operating systems, and you shouldn’t have much trouble getting the examples up and running. I’m hosting the code on GitHub because that will make it easy to update the implemen‐ tations over time. This also makes it possible for readers to contribute ports of the example clients and servers to other programming languages. Understanding Standards The World Wide Web isn’t an objective thing that’s out there to be studied scientifically. It’s a social construct—a set of agreements to do things a certain way. Fortunately, unlike other social constructs (like etiquette), the agreements underlying the Web are generally agreed upon. The core agreements underlying the human web are RFC 2616 (the HTTP standard), the W3C’s specification for HTML 4, and ECMA-262 (the standard that underlies JavaScript, also known as ECMAScript). Each standard does a different job, and over the course of this book, I’ll discuss dozens of other standards designed specif‐ ically for use in APIs. The great thing about these standards is the solid baseline they give you. You can use them to build a completely new kind of website or API, something that no one has ever tried before. Instead of having to explain your entire system to all your users, you’ll only have to explain the part that’s new. The bad news is that these agreements are often borderline unreadable: long walls of ASCII text written in tooth-achingly precise English in which everyday words like “should” have technical meanings and are capitalized “SHOULD.”4 A lot of technical books are bought by people who are hoping to avoid having to read a standards docu‐ ment. xxii | Introduction Well, I can’t make any guarantees. If one of these standards looks like something you can use in your work, you need to be willing to dive into its spec and really understand it (or buy a book that covers it in more detail). I don’t have space to give more than a basic overview of standards like Siren, CoAP, and Hydra. Not to mention that giving a lot of detail would bore all the readers who don’t need those particular standards to do their work. When navigating the forest of standards, it’s useful to keep in mind that not all standards have equal force. Some are extremely well established, used by everyone, and if you go against them you’re causing a lot of trouble for yoursef. Other standards are just one person’s opinion, and that opinion might be no better than yours. I find it helpful to divide standards into four categories: fiat standards, personal stand‐ ards, corporate standards, and open standards. I’ll be using these terms throughout the book, so let me explain each one in a bit more depth before we move on. Fiat Standards Fiat standards aren’t really standards; they’re behaviors. No one agreed to them. They’re just a description of the way somebody does things. The behavior may be documented, but the core assumption of a standard—that other people ought to do things the same way—is missing. Pretty much every API today is a fiat standard, a one-off design associated with a specific company. That’s why we talk about the “Twitter API,” the “Facebook API,” and the “Google+ API.” You may need to understand these designs to do your job and you may write your own clients for these designs, but unless you work for the company in ques‐ tion, there’s no expectation that you should use this design for your API. If you reuse a fiat standard, we don’t say your API conforms to a standard; we say it’s a clone. The main problem I’m trying to solve in this book is that hundreds of person-years of design work is locked up in fiat standards where it can’t be reused. This needs to stop. Designing a new API today means reinventing a long series of wheels. Once your API is finished, your client developers have to reinvent corresponding wheels on the client side. Even under ideal circumstances, your API will be a fiat standard, since your business requirements will be slightly different from everyone else’s. But ideally a fiat standard would be just a light gloss over a number of other standards. When I describe a fiat standard, I’ll link to its human-readable documentation. Personal Standards Personal standards are standards—you’re invited to read the documents and implement the standards yourself—but they’re just one person’s opinion. The Maze+XML standard Introduction | xxiii I describe in Chapter 5 is a good example. There’s no expectation that Maze+XML is the standard way to implement a maze game API, but if it works for you, you might as well use it. Someone else has done the design work for you. Personal standards generally use less formal language than other kinds of standards. Many open standards start off as personal standards—as side projects that are formal‐ ized after a lot of experimentation. Siren, which I cover in Chapter 7, is a good example. When I describe a personal standard, I’ll link to its specification. Corporate Standards Corporate standards are created by a consortium of companies trying to solve a problem that plagues them all, or by a single company trying to solve a recurring problem on behalf of its customers. Corporate standards tend to be better defined and to use more formal language than personal standards, but they have no more force than personal standards. They’re just one company’s (or a group of companies') opinion. Corporate standards include Activity Streams and schema.org’s microdata schemas, both of which are covered in Chapter 10. Many industry standards start off as corporate standards. OData (also discussed in Chapter 10) started as a Microsoft project, but it was submitted to OASIS in 2012 and will eventually become an OASIS standard. When I describe a corporate standard, I’ll link to its specification. Open Standards An open standard has gone through a process of design by committee, or at least had an open comment period during which a lot of people read the specification, complained about it, and made suggestions for improvement. At the end of this process, the speci‐ fication was blessed by some kind of recognized standards body. This process gives an open standard a certain amount of moral force. If there’s an open standard that does more or less what you want, you really should use it instead of making up your own fiat standard. The design process and the comment period probably turned up a lot of issues that you won’t encounter until it’s too late. In general, open standards come with some kind of agreement that promises you can implement them without getting hit with a patent infringement lawsuit from a company that was involved in the standards process. By contrast, implementing someone else’s fiat standard may incite them to file a patent infringement lawsuit against you. A few open standards mentioned in this book came out of the big-name standards bodies: ANSI, ECMA, ISO, OASIS, and especially the W3C. I can’t say what it’s like to sit on one of these standards bodies, because I’ve never done it. But the most important xxiv | Introduction 5. For the purposes of this book, anyway. If you need standard sizes for screws and bolts, you want ANSI or ISO. standards body5 is one anyone can contribute to: the IETF, the group that manages the all-important RFCs. Requests for Comments (RFCs) and Internet-Drafts Most RFCs are created through a process called the Standards Track. Throughout this book, I’ll be referencing documents that are in different places on the Standards Track. I’d like to briefly discuss how the track works, so that you’ll know how seriously to take my recommendations. An RFC begins life as an Internet-Draft. This is a document that looks like a standards document, but you’re not supposed to build implementations based on it. You’re sup‐ posed to find problems with the specification and give feedback. An Internet-Draft has a built-in lifetime of six months. Six months after it is published, a draft must be approved as an RFC or replaced with an updated draft. If neither of those things happens, then the draft expires and should not be used for anything. On the other hand, if the draft is approved, it expires immediately and is replaced by an RFC. Because of the built-in expiration date, and because an Internet-Draft isn’t technically any kind of standard, it’s tricky business mentioning them in a book. At the same time, API design is a field that’s changing rapidly, and an Internet-Draft is better than nothing. I will be mentioning many Internet-Drafts in this book under the assumption that they’ll become RFCs without major changes. That assumption has held up pretty well; several Internet-Drafts that I mention here became RFCs while I was writing the book. If a particular draft doesn’t pan out, all I can do is apologize in advance. RFCs and Internet-Drafts are given code names. When I describe one of these, I won’t link to its specification. I’ll just refer to it by its code and let you look it up. For example, I’ll refer to the HTTP/ 1.1 specification as RFC 2616. I’ll refer to an Internet-Draft by its name. For example, I’ll use “draft-snell-link-method” to refer to the proposal to add LINK and UNLINK methods to HTTP. Whenever you see one of these code names, you can do a web search and find the latest version of the RFC or Internet-Draft. If an Internet-Draft becomes an RFC after this book is published, the final version of the Internet-Draft will link to the RFC. When I describe a W3C or OASIS standard, I’ll link to the specification, because those standards aren’t given code names. Introduction | xxv Conventions Used in This Book The following typographical conventions are used in this book: Italic Indicates new terms, URLs, email addresses, filenames, and file extensions. Constant width Used for program listings, as well as within paragraphs to refer to program elements such as variable or function names, databases, data types, environment variables, statements, and keywords. Constant width bold Shows commands or other text that should be typed literally by the user. Constant width italic Shows text that should be replaced with user-supplied values or by values deter‐ mined by context. This icon signifies a tip, suggestion, or general note. This icon indicates a warning or caution. Using Code Examples This book is here to help you get your job done. In general, if this book includes code examples, you may use the code in this book in your programs and documentation. You do not need to contact us for permission unless you’re reproducing a significant portion of the code. For example, writing a program that uses several chunks of code from this book does not require permission. Selling or distributing a CD-ROM of examples from O’Reilly books does require permission. Answering a question by citing this book and quoting example code does not require permission. Incorporating a significant amount of example code from this book into your product’s documentation does require per‐ mission. We appreciate, but do not require, attribution. An attribution usually includes the title, author, publisher, and ISBN. For example: “RESTful Web APIs by Leonard Richardson and Mike Amundsen (O’Reilly). Copyright 2013 Leonard Richardson and amund‐ sen.com, Inc., and Sam Ruby. 978-1-449-35806-8.” xxvi | Introduction If you feel your use of code examples falls outside fair use or the permission given here, feel free to contact us at permissions@oreilly.com. Safari® Books Online Safari Books Online is an on-demand digital library that delivers expert content in both book and video form from the world’s lead‐ ing authors in technology and business. Technology professionals, software developers, web designers, and business and crea‐ tive professionals use Safari Books Online as their primary resource for research, prob‐ lem solving, learning, and certification training. Safari Books Online offers a range of product mixes and pricing programs for organi‐ zations, government agencies, and individuals. Subscribers have access to thousands of books, training videos, and prepublication manuscripts in one fully searchable database from publishers like O’Reilly Media, Prentice Hall Professional, Addison-Wesley Pro‐ fessional, Microsoft Press, Sams, Que, Peachpit Press, Focal Press, Cisco Press, John Wiley & Sons, Syngress, Morgan Kaufmann, IBM Redbooks, Packt, Adobe Press, FT Press, Apress, Manning, New Riders, McGraw-Hill, Jones & Bartlett, Course Technol‐ ogy, and dozens more. For more information about Safari Books Online, please visit us online. How to Contact Us Please address comments and questions concerning this book to the publisher: O’Reilly Media, Inc. 1005 Gravenstein Highway North Sebastopol, CA 95472 800-998-9938 (in the United States or Canada) 707-829-0515 (international or local) 707-829-0104 (fax) We have a web page for this book, where we list errata, examples, and any additional information. You can access this page at http://oreil.ly/RESTful-Web-APIs. To comment or ask technical questions about this book, send email to bookques tions@oreilly.com. For more information about our books, courses, conferences, and news, see our website at http://www.oreilly.com. Find us on Facebook: http://facebook.com/oreilly Follow us on Twitter: http://twitter.com/oreillymedia Introduction | xxvii Watch us on YouTube: http://www.youtube.com/oreillymedia Acknowledgements We owe a debt of thanks to Glenn Block who spent untold hours listening to ideas and working through real code to test those ideas. To Benjamin Young and all the folks at RESTFest who agreed to be part of our experiments, and who gave great feedback and advice even when we didn’t want to hear it. To Mike’s colleagues at Layer 7 Technologies, including Dimitri Sirota and Matt McLarty, who supported and encouraged his work on this project. To Sam Ruby and Mike Loukides, who were essential to RESTful Web Services, this book’s predecessor. To Sumana Harihareswara, Leonard’s supportive wife. To the social communities that create an excellent place to collaborate and converse on REST and APIs; especially Yahoo’s REST-Discuss, Google Groups’ API-Craft, and the Hypermedia group at LibreList. And finally, to all those who read the early drafts of this manuscript and provided much- needed criticism and support: Carsten Bormann, Todd Brackley, Tom Christie, Timothy Haas, Jamie Hodge, Alex James, David Jones, Markus Lanthaler, Even Maler, Mark Nottingham, Cheryl Phair, Sergey Shishkin, Brian Sletten, Mark Stafford, Stefan Tilkov, Denny Vrandečić, Ruben Verborgh, and Andrew Wahbe. xxviii | Introduction CHAPTER 1 Surfing the Web The World Wide Web became popular because ordinary people can use it to do really useful things with minimal training. But behind the scenes, the Web is also a powerful platform for distributed computing. The principles that make the Web usable by ordinary people also work when the “user” is an automated software agent. A piece of software designed to transfer money between bank accounts (or carry out any other real-world task) can accomplish the task using the same basic technologies a human being would use. As far as this book is concerned, the Web is based on three technologies: the URL naming convention, the HTTP protocol, and the HTML document format. URL and HTTP are simple, but to apply them to distributed programming you must understand them in more detail than the average web developer does. The first few chapters of this book are dedicated to giving you this understanding. The story of HTML is a little more complicated. In the world of web APIs, there are dozens of data formats competing to take the place of HTML. An exploration of these formats will take up several chapters of this book, starting in Chapter 5. For now, I want to focus on URL and HTTP, and use HTML solely as an example. I’m going to start off by telling a simple story about the World Wide Web, as a way of explaining the principles behind its design and the reasons for its success. The story needs to be simple because although you’re certainly familiar with the Web, you might not have heard of the concepts that make it work. I want you to have a simple, concrete example to fall back on if you ever get confused about terminology like “hypermedia as the engine of application state.” Let’s get started. 1 Episode 1: The Billboard One day Alice is walking around town and she sees a billboard (Figure 1-1). Figure 1-1. The billboard (By the way, this fictional billboard advertises a real website that I designed for this book. You can try it out yourself.) Alice is old enough to remember the mid-1990s, so she recalls the public’s reaction when URLs started showing up on billboards. At first, people made fun of these weird-looking strings. It wasn’t clear what “http://” or “youtypeitwepostit.com” meant. But 20 years later, everyone knows what to do with a URL: you type it into the address bar of your web browser and hit Enter. And that’s what Alice does: she pulls out her mobile phone and puts http://www.youtypeitwepostit.com/ in her browser’s address bar. The first episode of our story ends on a cliffhanger: what’s at the other end of that URL? Resources and Representations Sorry for interrupting the story, but I need to introduce some basic terminology. Alice’s web browser is about to send an HTTP request to a web server—specifically, to the URL http://www.youtypeitwepostit.com/. One web server may host many different URLs, and each URL grants access to a different bit of the data on the server. We say that a URL is the URL of some thing: a product, a user, the home page. The technical term for the thing named by a URL is resource. The URL http://www.youtypeitwepostit.com/ identifies a resource—probably the home page of the website advertised on the billboard. But you won’t know for sure until we resume the story and Alice’s web browser sends the HTTP request. 2 | Chapter 1: Surfing the Web When a web browser sends an HTTP request for a resource, the server sends a document in response (usually an HTML document, but sometimes a binary image or something else). Whatever document the server sends, we call that document a representation of the resource. So each URL identifies a resource. When a client makes an HTTP request to a URL, it gets a representation of the underlying resource. The client never sees a resource directly. I’ll talk a lot more about resources and representations in Chapter 3. Right now I just want to use the terms resource and representation to discuss the principle of address‐ ability, to which I’ll now turn. Addressability A URL identifies one and only one resource. If a website has two conceptually different things on it, we expect the site to treat them as two resources with different URLs. We get frustrated when a website violates this rule. Websites for restaurants are especially bad about this. Frequently, the whole site is buried inside a Flash interface and there’s no URL that points to the menu or to the map that shows where the restaurant is located —things we would like to talk about on their own. The principle of addressability just says that every resource should have its own URL. If something is important to your application, it should have a unique name, a URL, so that you and your users can refer to it unambiguously. Episode 2: The Home Page Back to our story. When Alice enters the URL from the billboard into her browser’s address bar, it sends an HTTP request over the Internet to the web server at http://www.youtypeitwepostit.com/: GET / HTTP/1.1 Host: www.youtypeitwepostit.com The web server handles this request (neither Alice nor her web browser need to know how) and sends a response: HTTP/1.1 200 OK Content-type: text/html Home

You type it, we post it!

Episode 2: The Home Page | 3

Exciting! Amazing!

The 200 at the beginning of the response is a status code, also called a response code. It’s a quick way for the server to tell the client approximately what happened to the client’s request. There are a lot of HTTP status codes, and I cover them all in Appendix A, but the most common one is the one you see here. 200 (OK) means that the request was fulfilled with no problems. Alice’s web browser decodes the response as an HTML document and displays it graph‐ ically (see Figure 1-2). Figure 1-2. You Type It… home page Now Alice can read the web page and understand what the billboard was talking about. It was advertising a microblogging site, similar to Twitter. Not as exciting as advertised on the billboard, but good enough as an example. Alice’s first real interaction with the web server reveals a couple more important features of the Web. Short Sessions At this point in the story, Alice’s web browser is displaying the site’s home page. From her perspective, she’s “landed” on that page, which is is her current “location” in cyber‐ space. But as far as the server is concerned, Alice isn’t anywhere. The server has already forgotten about her. 4 | Chapter 1: Surfing the Web HTTP sessions last for one request. The client sends a request, and the server responds. This means Alice could turn her phone off overnight, and when her browser restored the page from its internal cache, she could click on one of the two links on this page and it would still work. (Compare this to an SSH session, which is terminated if you turn your computer off.) Alice could leave this web page open in her phone for six months, and when she finally clicks on a link, the web server would respond as if she’d only waited a few seconds. The web server isn’t sitting up late at night worrying about Alice. When she’s not making an HTTP request, the server doesn’t know Alice exists. This principle is sometimes called statelessness. I think this is a confusing term because the client and the server in this system both keep state; they just keep different kinds of state. The term “statelessness” is getting at the fact that the server doesn’t care what state the client is in. (I’ll talk more about the different kinds of state in the following sections.) Self-Descriptive Messages It’s clear from looking at the HTML that this site is more than just a home page. The markup for the home page contains two links: one to the relative URL /about (i.e., to http://www.youtypeitwepostit.com/about) and one to /messages (i.e., http://www.youty peitwepostit.com/messages). At first Alice only knew one URL—the URL to the home page—but now she knows three. The server is slowly revealing its structure to her. We can draw a map of the website so far (Figure 1-3), as revealed to Alice by the server. Figure 1-3. A map of the website What’s on the other end of the /messages and /about links? The only way to be sure is to follow them and find out. But Alice can look at the HTML markup, or her browser’s graphical rendering of the markup, and make an educated guess. The link with the text “About this site” probably goes to a page talking about the site. That’s nice, but the link with the text “Get started” is probably the one that gets her closer to actually posting a message. Episode 2: The Home Page | 5 When you request a web page, the HTML document you receive doesn’t just give you the immediate information you asked for. The document also helps you answer the question of what to do next. Episode 3: The Link After reading the home page, Alice decides to give this site a try. She clicks the link that says “Get started.” Of course, whenever you click a link in your web browser, you’re telling your web browser to make an HTTP request. The code for the link Alice clicked on looks like this: Get started So her browser makes this HTTP request to the same server as before: GET /messages HTTP/1.1 Host: www.youtypeitwepostit.com That GET in the request is an HTTP method, also known as an HTTP verb. The HTTP method is the client’s way of telling the server what it wants to do to a resource. “GET” is the most common HTTP method. It means “give me a representation of this resource.” For a web browser, GET is the default. When you follow a link or type a URL into the address bar, your browser sends a GET request. The server handles this particular GET request by sending a representation of /messages: HTTP/1.1 200 OK Content-type: text/html ... Messages

Messages

Enter your message below:

6 | Chapter 1: Surfing the Web

Here are some other messages, too:

As before, Alice’s browser renders the HTML graphically (Figure 1-4). Figure 1-4. You Type It… “Get started” page When Alice looks at the graphical rendering, she sees that this page is a list of messages other people have published on the site. Right at the top there’s an inviting text box and a Post button. Now we’ve revealed a little more about how the server works. Figure 1-5 shows an updated map of the site, as seen by Alice’s browser. Episode 3: The Link | 7 Figure 1-5. The browser’s view of You Type It… Standardized Methods Both of Alice’s HTTP requests used GET as their HTTP method. But there’s a bit of HTML in the latest representation that will trigger an HTTP POST request if Alice clicks the Post button:
The HTTP standard (RFC 2616) defines eight methods a client can apply to a resource. In this book, I’ll focus on five of them: GET, HEAD, POST, PUT, and DELETE. In Chapter 3, I’ll cover these methods in detail, along with an extension method, PATCH, designed specifically for use in web APIs. Right now the important thing to keep in mind is that there are a small number of standard methods. It’s not impossible to come up with a new HTTP method (it happened with PATCH), but it’s a very big deal. This is not like a programming language, where you can name your methods whatever you want. When I built the simple microblogging website for use in this example, I didn’t define new HTTP methods like GETHOMEPAGE and HELLOPLEASESHOWMETHEMESSAGELISTTHANKSBYE. I used GET for both “show the home page” and “show the message list,” because in both cases GET (“give me a representation of this resource”) was the best match between HTTP’s interface and what I wanted to do. I distinguished between the home page and the message list not by defining new methods, but by treating those two documents as separate resources, each with its own URL, each accessible through GET. 8 | Chapter 1: Surfing the Web Episode 4: The Form and the Redirect Back to our story. Alice is tempted by the form on the microblogging site. She types in “Test” and clicks the Post button.: Again, Alice’s browser makes an HTTP request: POST /messages HTTP/1.1 Host: www.youtypeitwepostit.com Content-type: application/x-www-form-urlencoded message=Test&submit=Post And the server responds with the following: HTTP/1.1 303 See Other Content-type: text/html Location: http://www.youtypeitwepostit.com/messages/5266722824890167 When Alice’s browser made its two GET requests, the server sent the HTTP status code 200 (“OK”) and provided an HTML document for Alice’s browser to render. There’s no HTML document here, but the server did provide a link to another URL, in the Loca tion header—and here, the status code at the beginning of the response is 303 (“See Other”), not 200 (“OK”). Status code 303 tells Alice’s browser to automatically make a fourth HTTP request, to the URL given in the Location header. Without asking Alice’s permission, her browser does just that: GET /messages/5266722824890167 HTTP/1.1 This time, the browser responds with 200 (“OK”) and an HTML document: HTTP/1.1 200 OK Content-type: text/html Message

Message

ID
2181852539069950
DATE
2014-03-28T21:51:08Z
MSG
Test
Episode 4: The Form and the Redirect | 9
Alice’s browser displays this document graphically (Figure 1-6), and, finally, goes back to waiting for Alice’s input. Figure 1-6. You Type It… posted message I’m sure you’ve encountered HTTP redirects before, but HTTP is full of small features like this, and some may be new to you. There are many ways for the server to tell the client to handle a response differently, and ways for the client to attach conditions or extra features to its request. A big part of API design is the proper use of these features. Chapter 11 covers the features of HTTP that are most important to web APIs, and Appendix A and Appendix B provide supplementary information on this topic. By looking at the graphical rendering, Alice sees that her message (“Test”) is now a fully fledged post on YouTypeItWePostIt.com. Our story ends here—Alice has accomplished her goal of trying out the microblogging site. But there’s a lot to be learned from these four simple interactions. Application State Figure 1-7 is a state diagram that shows Alice’s entire adventure from the perspective of her web browser. 10 | Chapter 1: Surfing the Web Figure 1-7. Alice’s adventure: the client’s perspective When Alice started up the browser on her phone, it didn’t have any particular page loaded. It was an empty slate. Then Alice typed in a URL and a GET request took the browser to the site’s home page. Alice clicked a link, and a second GET request took the browser to the list of messages. She submitted a form, which caused a third request (a POST request). The response to that was an HTTP redirect, which Alice’s browser made automatically. Alice’s browser ended up at a web page describing the message Alice had just created. Every state in this diagram corresponds to a particular page (or to no page at all) being open in Alice’s browser window. In REST terms, we call this bit of information—which page are you on?—the application state. When you surf the Web, every transition from one application state to another corre‐ sponds to a link you decided to follow or a form you decided to fill out. Not all transitions are available from all states. Alice can’t make her POST request directly from the home page, because the home page doesn’t feature the form that allows her browser to con‐ struct the POST request. Resource State Figure 1-8 is a state diagram showing Alice’s adventure from the perspective of the web server. Resource State | 11 Figure 1-8. Alice’s adventure: the server’s perspective The server manages two resources: the home page (served from /) and the message list (served from /messages). (The server also manages a resource for each individual mes‐ sage. I’ve omitted those resources from the diagram for the sake of simplicity.) The state of these resources is called, simply enough, resource state. When the story begins, there are two messages in the message list: “Hello” and “Later.” Sending a GET to the home page doesn’t change resource state, since the home page is a static document that never changes. Sending a GET to the message list won’t change the state either. But when Alice sends a POST to the message list, it puts the server in a new state. Now the message list contains three messages: “Hello,” “Later,” and “Test.” There’s no way back to the old state, but this new state is very similar. As before, sending a GET to the home page or message list won’t change anything. But sending another POST to the message list will add a fourth message to the list. 12 | Chapter 1: Surfing the Web Because HTTP sessions are so short, the server doesn’t know anything about a client’s application state. The client has no direct control over resource state—all that stuff is kept on the server. And yet, the Web works. It works through REST—representational state transfer. Application state is kept on the client, but the server can manipulate it by sending rep‐ resentations—HTML documents, in this case—that describe the possible state transi‐ tions. Resource state is kept on the server, but the client can manipulate it by sending the server a representation—an HTML form submission, in this case—describing the desired new state. Connectedness In the story, Alice made four HTTP requests to YouTypeItWePostIt.com, and she got three HTML documents in return. Although Alice didn’t follow every single link in those documents, we can use those links to build a rough map of the website from the client’s perspective (Figure 1-9). Figure 1-9. What the client saw This is a web of HTML pages. The strands of the web are the HTML tags and
tags, each describing a GET or POST HTTP request Alice might decide to make. I call this the principle of connectedness: each web page tells you how to get to the adjoining pages. Connectedness | 13 The Web as a whole works on the principle of connectedness, which is better known as “hypermedia as the engine of application state,” sometimes abbreviated HATEOAS. I prefer “connectedness” or “the hypermedia constraint,” because “hypermedia as the en‐ gine of application state” sounds intimidating. But at this point, you should have no reason to find it intimidating. You know what application state is—it’s which web page a client is on. Hypermedia is the general term for things like HTML links and forms: the techniques a server uses to explain to a client what it can do next. To say that hypermedia is the engine of application state is to say that we all navigate the Web by filling out forms and following links. The Web Is Something Special Alice’s story doesn’t seem that exciting. because the World Wide Web has been the dominant Internet application for the past 20 years. But back in the 1990s, this was a very exciting story. If you compare the World Wide Web to its early competitors, you’ll see the difference. The Gopher protocol (defined in RFC 1436) looks a lot like HTTP, but it lacks address‐ ability. There is no succinct way to identify a specific document in Gopherspace. At least there wasn’t until the World Wide Web took pity on Gopherspace and released the URL standard (first defined in RFC 1738), which provides a gopher:// URL scheme that works just like http://. FTP, a popular pre-Web protocol for file transfer (defined in RFC 959), also lacks ad‐ dressability. Until RFC 1738 came along with its ftp:// URL scheme, there simply was no machine-readable way to point to a file on an FTP server. You had to use English prose to explain where the file was. It took the brainpower of a human being just to locate a file on a server. What a waste! FTP also featured long-lived sessions. A casual user could log on to an FTP server and tie up one of the server’s TCP connections indefinitely. By contrast, even a “persistent” HTTP connection shouldn’t tie up a TCP connection for longer than 30 seconds. The 1990s saw a lot of Internet protocols for searching different kinds of archives and databases—protocols like Archie, Veronica, Jughead, WAIS, and Prospero. But it turns out we don’t need all those protocols. We just need to be able to send GET requests to different kinds of websites. All these protocols died out or were replaced by websites. Their complex protocol-specific rules were folded into the uniformity of HTTP GET. Once the Web took over, it became a lot more difficult to justify creating a new appli‐ cation protocol. Why create a new tool that only techies will understand, when you can put up a website that anyone can use? All successful post-Web protocols do something the Web can’t do: peer-to-peer protocols like BitTorrent and real-time protocols like SSH. For most purposes, HTTP is good enough. 14 | Chapter 1: Surfing the Web 1. Fielding, Roy Thomas. Architectural Styles and the Design of Network-based Software Architectures. Doctoral dissertation, University of California, Irvine, 2000. The unprecedented flexibility of the Web comes from the principles of REST. In the 1990s, we discovered that the Web works better than its competition. In 2000, Roy T. Fielding’s Ph.D dissertation1 explained why this is, coining the term “REST” in the pro‐ cess. Web APIs Lag Behind the Web The Fielding dissertation also explains a lot about the problems of web APIs in the 2010s. The simple website I just walked you through is much more sophisticated than most currently deployed web APIs—even self-proclaimed REST APIs. If you’ve ever designed a web API, or written a client for one, you’ve probably encountered some of these prob‐ lems: • Web APIs frequently have human-readable documentation that explains how to construct URLs for all the different resources. This is like writing English prose explaining how to find a particular file on an FTP server. If websites did this, no one would bother to use the Web. Instead of telling you what URLs to type in, websites embed URLs in tags and tags—hypermedia controls that you can activate by clicking a link or a button. In REST terms, putting information about URL construction in separate human- readable documents violates the principles of connectedness and self-descriptive messages. • Lots of websites have help docs, but when was the last time you used them? Unless there’s a serious problem (you bought something and it was never delivered), it’s easier to click around and figure out how the site works by exploring the connected, self-descriptive HTML documents it sends you. Today’s APIs present their resources in a big menu of options instead of an inter‐ connected web. This makes it difficult to see what one resource has to do with another. • Integrating with a new API inevitably requires writing custom software, or instal‐ ling a one-off library written by someone else. But you don’t need to write custom software to use a new website. You see a URL on a billboard and plug it into your web browser—the same client you use for every other website in the world. We’ll never get to the point where a single API client can understand every API in the world. But today’s clients contain a lot of code that really ought to be refactored Web APIs Lag Behind the Web | 15 out into generic libraries. This will only become possible when APIs serve self- descriptive representations. • When APIs change, custom API clients break and have to be fixed. But when a website undergoes a redesign, the site’s users grumble about the redesign and then they adapt. Their browsers don’t stop working. In REST terms, the website redesign is entirely encapsulated in the self-descriptive HTML documents served by the website. A client that could understand the old HTML documents can understand the new ones. These are the problems I’m trying to solve with this book. The good news is that it used to be a lot worse. A few years ago, it was common to see RESTful APIs that used safe HTTP methods in unsafe ways, or mixed up application and resource state. This doesn’t happen much anymore. Designs have gotten better, and they can get better still. The Semantic Challenge Now for the bad news. The story I’ve told you, the story of Alice’s trip through a website, went as smoothly as it did thanks to a very slow and expensive piece of hardware: Alice herself. Every time her browser rendered a web page, Alice, a human being, had to look at the rendered page and decide what to do next. The Web works because human beings make all the decisions about which links to click and which forms to fill out. The whole point of web APIs is to get things done without making a human sit in front of a web browser all day. How can we program a computer to make the decisions about which links to click? A computer can parse the HTML markup Get started, but it can’t understand the phrase “Get started.” Why bother to design APIs that serve self-descriptive messages if those messages won’t be understood by their software consumers? This is the biggest challenge in web API design: bridging the semantic gap between understanding a document’s structure and understanding what it means. As a short‐ hand, I’m going to call it the semantic challenge. Very little progress has been made on the semantic challenge, and we will never solve it completely. The good news is that because so little progress has been made so far, the first bit of progress is really easy. We just have to start working together, instead of duplicating each other’s work. I’ll be checking in with the semantic challenge over the next few chapters, as I talk about the technologies of the Web and how you can use them in API designs. By Chapter 8, we’ll have the tools necessary to tackle the semantic challenge head-on. 16 | Chapter 1: Surfing the Web CHAPTER 2 A Simple API In Chapter 1, I showed off a very simple microblogging website located at http:// www.youtypeitwepostit.com/. As it happens, I’ve also designed a programmable API for this website. You can see it live at http://www.youtypeitwepostit.com/api/. The ideal API would have the same characteristics that make the World Wide Web easy to use. As a developer, you would be able to figure out how to use it, starting with nothing but a URL you saw on a billboard. Let’s spin out that fantasy to see how it would work. First, you would have your pro‐ grammable client make a GET request for the billboard URL—the equivalent to entering that URL into your web browser’s address bar. Your client would take over from there, examining the response to see what the available options are. It would follow links (not necessarily HTML links), fill out forms (not necessarily HTML forms), and eventually accomplish the task you set out for it. This book is not going to get us all the way to that goal. There are problems I can’t solve with a book: problems surrounding the absence of standards, problems with the current level of tool support, and the brute fact that computers just aren’t as smart as human beings. But we can get a long way toward that goal—a lot further than you may think. As I said, there is a real microblogging API at http://www.youtypeitwepostit.com/api/. If you’re feeling adventurous, go ahead and write some code to do something with that API. See how much you can figure out, knowing nothing but that URL. You’ve done this before with websites: all you knew was the home page URL, and you figured it out. How far can you get with an API? If you’re not feeling adventurous or don’t have much experience writing clients for web APIs (or you’re reading this book in the far future, and I’m not hosting that website anymore), we’ll go through it together. The first step is to get a representation of the API’s home page. 17 HTTP GET: Your Safe Bet If you have a URL that starts with http:// or https://, and you don’t know what’s on the other side, the first thing to do is to issue an HTTP GET request. In REST terms, you know the URL to a resource and nothing else. You need to discover your options, and that means getting a representation of the resource. That’s what HTTP GET is for. You can write code in a programming language to make that GET request, but when doing an initial reconnaissance of an API, it’s often easier to use a command-line tool like Wget. Here I use the -S option, which prints out the full HTTP response from the server, and the -O - option, which prints out the document instead of saving it to a file: $ wget -S -O - http://www.youtypeitwepostit.com/api/ This sends an HTTP request like this to the server: GET /api/ HTTP/1.1 Host: www.youtypeitwepostit.com The HTTP standard says that a GET request is a request for a representation. It’s not intended to change any resource state on the server. This means that if you have a URL to a resource and don’t know anything more, you can always make a GET request and get a representation in return. Your GET request won’t do something disastrous like delete all the data. We say that GET is a safe method. It’s OK for the server to change incidental things because of a GET request, like incre‐ menting a hit counter or logging the request to a file, but that’s not the purpose of the GET request. Nobody makes an HTTP request just to increment the hit counter. In real life, there’s no guarantee that HTTP GET is safe. Some older designs will force you to make an HTTP GET request if you want to delete some data. But this misfeature is pretty rare in newer designs. Most API designers now understand that clients fre‐ quently GET a URL just to see what’s behind it. It’s not fair to give that GET request significant side effects. How to Read an HTTP Response In response to my GET request, the server sends a big chunk of data that looks like this: HTTP/1.1 200 OK ETag: "f60e0978bc9c458989815b18ddad6d75" Last-Modified: Thu, 10 Jan 2013 01:45:22 GMT Content-Type: application/vnd.collection+json { "collection": { "version" : "1.0", "href" : "http://www.youtypeitwepostit.com/api/", "items" : [ 18 | Chapter 2: A Simple API { "href" : "http://www.youtypeitwepostit.com/api/messages/21818525390699506", "data": [ { "name": "text", "value": "Test." }, { "name": "date_posted", "value": "2013-04-22T05:33:58.930Z" } ], "links": [] }, { "href" : "http://www.youtypeitwepostit.com/api/messages/3689331521745771", "data": [ { "name": "text", "value": "Hello." }, { "name": "date_posted", "value": "2013-04-20T12:55:59.685Z" } ], "links": [] }, { "href" : "http://www.youtypeitwepostit.com/api/messages/7534227794967592", "data": [ { "name": "text", "value": "Pizza?" }, { "name": "date_posted", "value": "2013-04-18T03:22:27.485Z" } ], "links": [] } ] }, "template": { "data": [ {"prompt": "Text of message", "name": "text", "value":""} ] } } How much can we learn from this? Well, every HTTP response can be split into three parts: The status code, sometimes called the response code This is a three-digit number that summarizes how the request went. The response code is the first thing an API client sees, and it sets the tone for the rest of the response. Here, the status code was 200 (OK). This is the status code a client hopes for—it means that everything went fine. In Appendix A, I explain all of the standard HTTP response codes, as well as several useful extensions. The entity-body, sometimes called just the body This is a document written in some data format, which the client is expected to understand. If you think of a GET request as a request for a representation, you can think of the entity-body as the representation (technically, the entire HTTP re‐ How to Read an HTTP Response | 19 sponse is the ‘representation’, but the important information is usually in the entity- body). In this case, the entity-body is the huge document at the end of the response, the one full of curly brackets. The response headers These are a series of key-value pairs describing the entity-body and the HTTP re‐ sponse in general. Response headers are sent between the status code and the entity- body. In Appendix B, I explain all the standard HTTP headers and many useful extensions. The most important HTTP header is Content-Type, which tells the HTTP client how to understand the entity-body. It’s so important that its value has a special name. We say the value of the Content-Type header is the entity-body’s media type. (It’s also called the MIME type or the content type. Sometimes “media type” is hyphenated: media-type.) On the part of the Web that human beings can see with their web browsers, the most common media types are text/html (for HTML) and image types like image/ jpeg. Here, the media type is one you probably haven’t seen before: application/ vnd.collection+json. JSON If you’re a web developer, you probably recognize this entity-body as a JSON document. In case you don’t, here’s a very quick introduction to JSON. JSON, described in RFC 4627, is a standard for representing simple data structures in plain text. It uses double quotes to describe strings: "this is a string" It uses square brackets to describe lists: [1, 2, 3] It uses curly brackets to describe objects (collections of key-value pairs): {"key": "value"} JSON data looks a lot like JavaScript or Python code. The JSON standard puts con‐ straints on plain text. It says that a bare string like It was the best of times. is unacceptable, even though a human being can look at it and see what’s going on. To be valid JSON, a string has to go inside double quotes: "It was the best of times." 20 | Chapter 2: A Simple API 1. Collection+JSON is a personal standard defined at this page. Collection+JSON So, this entity-body document is JSON, right? Not so fast! You can feed this document into a JSON parser without crashing the parser, but that’s not what the web server wants you to do. Here’s what the server said: Content-Type: application/vnd.collection+json That conflicts with the JSON RFC, which says a JSON document should be served as application/json, like this: Content-Type: application/json So what is this application/vnd.collection+json stuff? Clearly this format is based on JSON, since it looks like JSON and its media type has “json” in the name. But what is it, really? If you search the web for application/vnd.collection+json, you’ll discover that it’s a media type registered for Collection+JSON.1 When you make a GET request to http:// www.youtypeitwepostit.com/api/, you don’t get just any JSON document—you get a Collection+JSON document. In Chapter 6, I’ll talk about Collection+JSON in detail, but here’s the short version. Collection+JSON is a standard for publishing a searchable list of resources over the Web. JSON puts constraints on plain text, and Collection+JSON puts constraints on JSON. A server can’t serve just any JSON document as application/vnd.collection +json. It can only serve a JSON object: {} But not just any object. The object has to have a property called collection, which maps to another object: {"collection": {}} The “collection” object ought to have a property called items that maps to a list: {"collection": {"items": []}} The items in the “items” list need to be objects: {"collection": {"items": [{}, {}, {}]}} And on and on, constraint after constraint. Eventually you get the highly formatted document you just saw, which starts out like this: { "collection": { "version" : "1.0", Collection+JSON | 21 "href" : "http://www.youtypeitwepostit.com/api/", "items" : [ { "href" : "http://www.youtypeitwepostit.com/api/messages/21818525390699506", "data": [ { "name": "text", "value": "Test." }, { "name": "date_posted", "value": "2013-04-22T05:33:58.930Z" } ], "links": [] }, ... } Look at the document as a whole, and the purpose of all these constraints becomes clear. Collection+JSON is a way of serving lists—not lists of data structures, which you can do with normal JSON, but lists that describe HTTP resources. The collection object has an href property, and its value is a JSON string. But it’s not just any string—it’s the URL I just sent a GET request to: { "collection": { "href" : "http://www.youtypeitwepostit.com/api/" } } The Collection+JSON standard defines this string as “the address used to retrieve a representation of the document” (in other words, it’s the URL of the collection re‐ source). Each object inside the collection’s items list has its own href property, and each value is a string containing a URL, like http://www.youtypeitwepostit.com/api/messages/ 21818525390699506 (in other words, each item in the list represents an HTTP resource with its own URL). A document that doesn’t follow these rules isn’t a Collection+JSON document: it’s just some JSON. By allowing yourself to be bound by Collection+JSON’s constraints, you gain the ability to talk about concepts like resources and URLs. These concepts are not defined in JSON, which can only talk about simple things like strings and lists. Writing to an API How would I use the API to publish a message to the microblog? Here’s what the Col‐ lection+JSON specification has to say: To create a new item in the collection, the client first uses the template object to compose a valid item representation and then uses HTTP POST to send that representation to the server for processing. That’s not exactly a step-by-step description, but it points toward the answer. Collection +JSON works along the same lines as HTML. The server provides you with some kind 22 | Chapter 2: A Simple API of form (the template), which you fill out to create a document. Then you send that document to the server with a POST request. Again, Chapter 6 covers Collection+JSON in detail, so here’s the quick version. Look at the big object I showed you earlier. Its template property is the "template object” men‐ tioned in the Collection+JSON specification: { ... "template": { "data": [ {"prompt": "Text of message", "name": "text", "value":""} ] } To fill out the template, I replace the empty string under value with the string I want to publish: { "template": { "data": [ {"prompt": "Text of the message", "name": "text", "value": "Squid!"} ] } } I then send the filled-out template as part of an HTTP POST request: POST /api/ HTTP/1.1 Host: www.youtypeitwepostit.com Content-Type: application/vnd.collection+json { "template": { "data": [ {"prompt": "Text of the message", "name": "text", "value": "Squid!"} ] } } (Note that my request’s Content-Type is application/vnd.collection+json. This filled-out template is a valid Collection+JSON document all on its own.) The server responds: HTTP/1.1 201 Created Location: http://www.youtypeitwepostit.com/api/47210977342911065 The 201 response code (Created) is a little more specific than 200 (OK); it means that everything is OK and that a new resource was created in response to my request. The Location header gives the URL to the newborn resource. Writing to an API | 23 In Chapter 1, Alice posted to the microblogging site using the web interface. Now I’ve successfully done the same thing using the site’s web API. HTTP POST: How Resources Are Born To add a new item to a collection, you send a POST request to the URL of the collection. This isn’t just how Collection+JSON does things. It’s a basic fact about HTTP. RFC 2616, the HTTP specification, has this to say about POST: POST is designed to allow a uniform method to cover the following functions: • Annotation of existing resources; • Posting a message to a bulletin board, newsgroup, mailing list, or similar group of articles; • Providing a block of data, such as the result of submitting a form, to a data-handling process; • Extending a database through an append operation. That second bullet point, “posting a message to a… group of articles,” covers the mi‐ croblog exactly. The POST request I sent looks a lot like an HTTP response. It’s got a Content-Type header and an entity-body. Although the GET request I showed earlier didn’t provide any headers, any HTTP request can have headers, and there are a number of headers (such as Accept) that are very important in GET requests. I’ll be discussing especially important HTTP headers as they show up, but be sure to consult Appendix B for the complete list of standard HTTP headers. Let’s move on. Once again, here’s the response I got to my POST request: 201 Created Location: http://www.youtypeitwepostit.com/api/47210977342911065 When you get a 201 response code, the Location header tells you where to look for the thing you just created. RFC 2616 specifies the meaning of the 201 response code and the Location header, but the Collection+JSON specification mentions this as well, just to be clear. If I send the following GET request: GET /api/47210977342911065 HTTP/1.1 Host: www.youtypeitwepostit.com I’ll see a familiar sight: HTTP/1.1 200 OK Content-Type: application/vnd.collection+json 24 | Chapter 2: A Simple API { "collection": { "version" : "1.0", "href" : "http://www.youtypeitwepostit.com/api/47210977342911065", "items" : [ { "href" : "http://www.youtypeitwepostit.com/api/messages/47210977342911065", "data": [ { "name": "date_posted", "value": "2014-04-20T20:15:32.858Z" }, { "name": "text", "value": "Squid!" } ], "links": [] } ] } } This individual microblog post is represented as a full application/vnd.collection +json document. It’s a collection with an items list that only contains one item. The filled-out template was also a valid application/vnd.collection+json document, even though it didn’t use the collection property at all. This is a convenience feature of Collection+JSON. Almost everything in the document is optional. It means you don’t have to write different parsers to handle different types of documents. Collection+JSON uses the same JSON format to represent lists of items, individual items, filled-out templates, and search results. Liberated by Constraints One counterintuitive lesson of RESTful design is that constraints can be liberating. The safety constraint of HTTP’s GET method is a good example. Thanks to the safety con‐ straint, you know that if you don’t know what to do with a URL, you can always GET it and look at the representation. Even if that doesn’t help, nothing terrible will happen just because you made a GET request. That’s a liberating promise, and it’s only possible because of a very severe constraint on the server side. If the server sends you a plain text document that says 9, you have no way to know if it’s supposed to be the number nine or the string “9”. But if you get a JSON document that says 9, you know it’s a number. The JSON standard constrains the meaning of the document, and that makes it possible for client and server to have a meaningful con‐ versation. Over the past few years, hundreds of companies have gone through this general line of thinking: 1. We need an API. 2. We’ll use JSON as the document format. Liberated by Constraints | 25 3. We’ll use JSON to publish lists of things. All three of these are good ideas, but they don’t say much about what the API should look like. The end result is hundreds of APIs that are superficially similar (they all use JSON to publish lists of things!) but completely incompatible. Learning one API doesn’t help a client learn the next one. This is a sign that more constraints are necessary. The Collection+JSON standard pro‐ vides some more constraints. If I’d come up with my own custom API design instead of using Collection+JSON, an individual item in my list might have looked like this: { "self_link": "http://www.youtypeitwepostit.com/api/messages/47210977342911065", "date": "2014-04-20T20:15:32.858Z", "text": "Squid!" } Instead, because I followed the Collection+JSON constraints, an individual item looks like this: { "href" : "http://www.youtypeitwepostit.com/api/messages/1xe5", "data": [ { "name": "date_posted", "value": "2014-04-20T20:15:32.858Z" }, { "name": "text", "value": "Squid!" } ], "links": [] } The custom design is certainly more compact, but that’s not very important—JSON compresses very well. In exchange for this less compact representation, I get a number of useful features: • I don’t have to tell all my users that the value of href is a URL, and I don’t have to explain what it’s the URL of. The Collection+JSON standard says that an item’s href contains the URL to the item. • I don’t have to write a separate human-readable document explaining to my users that text is the text of the message. That information goes where it’s actually needed —in the template you fill out to post a new message: "template": { "data": [ {"prompt": "Text of the message", "name": "text", "value": null} ] } • Any library that understands application/vnd.collection+json automatically knows how to use my API. If I came up with a custom design, I’d have to write 26 | Chapter 2: A Simple API brand new client code based on nothing but a JSON parser and an HTTP library, or ask all my users to write that code themselves. By submitting to the Collection+JSON constraints, I free myself from having to write a whole lot of documentation and code, and I free my users from having to learn yet another custom API. Application Semantics Create the Semantic Gap Of course, the Collection+JSON constraints don’t constrain everything. Collection +JSON doesn’t specify that the items in a collection should be microblog posts with a date_posted and a text. I made that part up, because I wanted to design a simple microblogging example for this book. If I’d chosen to do a “recipe book” example, I could still use Collection+JSON, but the items would have data fields like ingredi ents and preparation_time. I’m going to call these extra bits of design the application semantics, because they vary from one application to another. Application semantics are the cause of the semantic gap I mentioned in Chapter 1. If I were designing a real microblogging API, I’d come up with application semantics more complicated than just text and date_posted. That’s fine, on its own. But there are currently dozens of companies designing microblogging APIs, coming up with dozens of designs that feature mutually incompatible application semantics, creating dozens of distinct semantic gaps. All of these companies are doing the same thing in different ways. Their users have to write different software clients to accomplish the same task. The fact that Collection+JSON doesn’t solve this problem doesn’t mean there’s no point to using Collection+JSON. Compatibility is a matter of degree. We took a big step toward compatibility in the 1990s when we stopped inventing custom Internet protocols and standardized on HTTP. If we all agreed to serve JSON documents, that might not be a good idea technically, but it would narrow the semantic gap. Standardizing on Collec‐ tion+JSON would narrow it even more. If the publishers of microblogging APIs got together and agreed to use a common set of application semantics, the semantic gap for microblogging would disappear almost entirely. (This would be a profile, and I’ll cover this idea in Chapter 8.) The more con‐ straints we share and the more compatible our designs, the smaller the semantic gap and the more our users benefit. Application Semantics Create the Semantic Gap | 27 Maybe you don’t want your API to be interoperable with your competitor’s APIs, but there are better ways to differentiate yourself than by artificially widening the semantic gap. My goal for this book is to get you focused on the parts of your API that have something new to offer, in the spots where a semantic gap exists because no one else has ever taken that path. 28 | Chapter 2: A Simple API CHAPTER 3 Resources and Representations So far I’ve shown you two examples of REST in action: a website (Chapter 1) and a web API (Chapter 2). I’ve talked in terms of examples, because there’s no RFC for REST the way there is for HTTP or JSON. REST is not a protocol, a file format, or a development framework. It’s a set of design constraints: statelessness, hypermedia as the engine of application state, and so on. Col‐ lectively, we call these the Fielding constraints, because they were first identified in Roy T. Fielding’s 2000 dissertation on software architecture, which gathered them together under the name “REST.” The runaway popularity of the term “REST” is out of proportion to the importance of REST to Fielding’s dissertation. Fielding used REST primarily as an example, to tie something you’re already familiar with (the Web) into a general design process. REST became popular because the term happens to describe the architecture of one of the most successful technologies in human history. In this chapter, I’ll finish my explanation of the Fielding constraints in terms of the World Wide Web. My “bible,” as it were, will not be the Fielding dissertation. (You can see Appendix C for a detailed, API-centric discussion of Fielding.) Instead, I’ll be draw‐ ing from the W3C’s guide to the Web, The Architecture of the World Wide Web, Volume One (there is no Volume Two). The Fielding dissertation explains the decisions behind the design of the Web, but Architecture explains the three technologies that came out of those decisions: URL, HTTP, and HTML. I’m sure you already know about these technologies, but understanding them on a deep level is the key to understanding the Fielding constraints, how those constraints drive the success of the Web, and how you can exploit those constraints in your own APIs. Underlying the three web technologies are two essential concepts: resources and repre‐ sentations. I’ve mentioned them before, but now it’s time to take a closer look. 29 A Resource Can Be Anything A resource is anything that’s important enough to be referenced as a thing in itself. If your users might “want to create a hypertext link to it, make or refute assertions about it, retrieve or cache a representation of it, include all or part of it by reference into another representation, annotate it, or perform other operations on it” (Architecture), you should make it a resource. A resource is usually something that can be stored on a computer: an electronic docu‐ ment, a row in a database, or the result of running an algorithm. Architecture calls these “information resources,” because their native form is a stream of bits. But a resource can be anything at all: a pomegranate, a human being, the color black, the concept of courage, the relationship between mother and daughter, or the set of all prime numbers. The only restriction is that every resource must have a URL. Do you remember that thing, the thing you had a while ago, but then… do you know what I’m talking about? Of course you don’t. I wasn’t specific enough. I could have been talking about anything. It’s the same on the Web. Clients and servers can only talk about something if they can agree on a name for it. On the Web, we use a URL to give each resource a globally unique address. Giving something a URL turns it into a resource. From the client’s perspective, it doesn’t matter what a resource is, because the client never sees a resource. All it ever sees are URLs and representations. A Representation Describes Resource State A pomegranate can be an HTTP resource, but you can’t transmit a pomegranate over the Internet. A row in a database can be an HTTP resource; in fact, it can be an infor‐ mation resource, because you can literally send it over the Internet. But what would the client do with a chunk of binary data, ripped from an unknown database without any context? When a client issues a GET request for a resource, the server should serve a document that captures the resource in a useful way. That’s a representation—a machine-readable explanation of the current state of a resource. The size and ripeness of the pomegranate, the data contained in the database fields. The server might describe a database row as an XML document, a JSON object, a set of comma-separated values, or as the SQL INSERT statement used to create it. These are all legitimate representations; it depends on what the client asks for. One application might represent a pomegranate as an item for sale, using a custom XML vocabulary. Another might represent it with a binary image taken by a Pomegranate- Cam. It depends on the application. A representation can be any machine-readable document containing any information about a resource. 30 | Chapter 3: Resources and Representations Representations Are Transferred Back and Forth In Chapter 2, I showed a client using a POST request to create a new microblog entry. The client then sent an HTTP GET request, asking for a representation of the new entry: GET /api/5266722824890167 HTTP/1.1 Host: www.youtypeitwepostit.com The server responded with a representation in application/vnd.collection+json format, which looked like this: HTTP/1.1 200 OK Content-Type: application/vnd.collection+json ... { "collection" : { "version" : "1.0", "href" : "http://localhost:1337/api/", "items" : [{ "href": "http://localhost:1337/api/5266722824890167", "data": [ { "name": "text", "value": "tasting" }, { "name": "date_posted", "value": "2013-01-09T15:58:22.674Z" } ] }], "template" : { "data" : [ { "prompt" : "Text of message", "name" : "text", "value" : "" } ] } } } But there’s another representation of that entry: the one the client sent to the server in the first place, along with the POST request. That was also an application/vnd.collec tion+json document, and it looked like this: Representations Are Transferred Back and Forth | 31 { "template": { "data": [ {"prompt": "Text of the message", "name": "text", "value": "Squid."} ] } } The two representations look significantly different. One of them has the essential in‐ formation in a template object, and the other has it in an items list. But they’re clearly different representations of the same resource: a microblog entry that says, “Squid.” When a client makes a POST request to create a new resource, it sends a representation: the client’s idea of what the new resource should look like. The server’s job is to create that resource, or else refuse to create it. The client’s representation is just a suggestion. The server may add to, alter, or ignore any part of it. (Here, the server added a date_pos ted value to the data.) The Web works the same way. Back in Chapter 1, my fictional character Alice created a new entry on a microblogging website by sending a POST request, along with a rep‐ resentation in application/x-www-form-urlencoded format: message=Test&submit=Post That doesn’t look anything like the complex HTML document Alice got in return, but they were both representations of a microblog post that says, “Test.” We think of representations as something the server sends to the client. That’s because when we surf the Web, most of our requests are GET requests. We’re asking for repre‐ sentations. But in a POST, PUT, or PATCH request, the client sends a representation to the server. The server’s job is then to change the resource state so it reflects the incoming representation. The server sends a representation describing the state of a resource. The client sends a representation describing the state it would like the resource to have. That’s represen‐ tational state transfer. Resources with Many Representations A resource can have more than one representation. Government documents are often made available in multiple languages. Some resources have an overview representation that doesn’t convey much state, and a detail representation that includes everything. Some APIs serve the same data in JSON and XML-based data formats. When this hap‐ pens, how is the client supposed to specify which representation it wants? There are two strategies, and I’ll describe them in detail in Chapter 11. The first is content negotiation, in which the client distinguishes between representations based on the 32 | Chapter 3: Resources and Representations 1. “Hey, Mike!”, “@mamund”, “Good evening, Mr. Amundsen.” value of an HTTP header. The second is to give the resource multiple URLs—one URL for every representation. Just as one person may be addressed by different names in different contexts,1 one resource may be identified by many URLs. When this happens, the server that publishes the resource should designate one of those URLs the official or “canonical” URL. I’ll cover those details, too, in Chapter 11. The Protocol Semantics of HTTP Although a resource can be anything at all, a client can’t do whatever it wants to a resource. There are rules. In a RESTful system, clients and servers interact only by sending each other messages that follow a predefined protocol. In the world of web APIs, that protocol is HTTP. (But see Chapter 13 for a RESTful API architecture that doesn’t use HTTP.) API clients can interact with APIs by sending a few different types of HTTP messages. The HTTP standard defines eight different kinds of messages. These four are the most commonly used: GET Get a representation of this resource. DELETE Destroy this resource. POST Create a new resource underneath this one, based on the given representation. PUT Replace this state of this resource with the one described in the given representation. These two methods are mostly used as a client explores an API: HEAD Get the headers that would be sent along with a representation of this resource, but not the representation itself. OPTIONS Discover which HTTP methods this resource responds to. The other two methods defined in the HTTP standard, CONNECT and TRACE, are only used with HTTP proxies. I won’t be covering them. The Protocol Semantics of HTTP | 33 I recommend that API designers consider a ninth HTTP method, defined not in the HTTP standard but in a supplement, RFC 5789: PATCH Modify part of the state of this resource based on the given representation. If some bit of resource state is not mentioned in the given representation, leave it alone. PATCH is like PUT, but allows for fine-grained changes to resource state. I’d also like you to know about two extension HTTP methods that are currently going through the standards process. They’re defined in the Internet-Draft “snell-link- method,” and I’ll come back to them in Chapter 11, at which point they should make a lot more sense: LINK Connect some other resource to this one. UNLINK Destroy the connection between some other resource and this one. Collectively, these methods define the protocol semantics of HTTP. Just by looking at the method used in an HTTP request, you can understand approximately what the client wants: whether it’s trying to get a representation, delete a resource, or connect two resources together. You can’t understand exactly what’s going on, because a resource can be anything at all. A GET request sent to a “blog post” resource looks just like the GET request sent to a “stock symbol” resource. Those two requests have identical protocol semantics, but different application semantics. HTTP is HTTP, but a blogging API is not a stock quote API. We can’t meet the semantic challenge just by using HTTP correctly, because the HTTP protocol doesn’t define any application semantics. But your application semantics should always be consistent with HTTP’s protocol semantics. “Get a blog post” and “get a stock quote” both fall under “get a representation of this resource,” so both requests should use HTTP GET. The following sections provide a more detailed look at the protocol semantics of the most popular HTTP methods. GET You’re surely familiar with this method already. The client sends a GET request to ask for a representation of a resource, identified by a URL. Here, the client asks for a rep‐ resentation of a microblog post, and the server sends it in application/vnd.collec tion+json format: GET /api/45ty HTTP/1.1 Host: www.youtypeitwepostit.com 34 | Chapter 3: Resources and Representations HTTP/1.1 200 OK Content-Type: application/vnd.collection+json ... { "collection" : { "version" : "1.0", "href" : "http://localhost:1337/api/", "items" : [{ "href": "http://localhost:1337/api/2csl73jr6j5", "data": [ { "name": "text", "value": "Bird" }, { "name": "date_posted", "value": "2013-01-24T18:40:42.190Z" } ] }], "template" : { "data" : [ {"prompt" : "Text of message", "name" : "text", "value" : ""} ] } } } I mentioned earlier that GET is defined as a safe HTTP method. It’s just a request for information. Sending a GET request to the server should have the same effect on re‐ source state as not sending a GET request—that is, no effect at all. Incidental side effects like logging and rate limiting are OK, but a client should never make a GET request hoping that it will change the resource state. The most common response code to a GET request is 200 (OK). Redirect codes like 301 (Moved Permanently) are also common. DELETE The client sends a DELETE request when it wants a resource to go away. The client wants the server to destroy the resource and never refer to it again. Of course, the server is not obliged to delete something it doesn’t want to. In this HTTP snippet, the client asks to delete a microblog post: The Protocol Semantics of HTTP | 35 DELETE /api/45ty HTTP/1.1 Host: www.youtypeitwepostit.com The server returns the status code 204 (No Content), indicating that it’s deleted the post and has nothing more to say about it: HTTP/1.1 204 No Content If a DELETE request succeeds, the possible status codes are 204 (No Content, i.e., “it’s deleted, and I don’t have anything more to say about it”), 200 (OK, i.e., “it’s deleted, and here’s a message about that”); and 202 (Accepted, i.e., “I’ll delete it later”). If a client tries to GET a resource that has been DELETEd, the server will return an error response code, usually 404 (Not Found) or 410 (Gone): GET /api/45ty HTTP/1.1 Host: www.youtypeitwepostit.com HTTP/1.1 404 Not Found Idempotence DELETE is obviously not a safe method. Sending a DELETE request is very different from not sending a DELETE request. But the DELETE method has another useful property: it’s idempotent. Once you delete a resource, it’s gone. The resource state has permanently changed. You can send another DELETE request, and you might get a 404 error, but the resource state is exactly as it was after the first request. The resource is still gone. That’s idempotence. Sending a request twice has the same effect on resource state as sending it once. Idempotence is a useful feature, because the Internet is not a reliable network. Suppose you send a DELETE request and your connection times out. You never got a response, so you don’t know if the DELETE went through. You can just send that DELETE request again, and keep trying until you get a response. Nothing extra will happen if a DELETE goes through twice instead of once. The notion of idempotence comes from math. Multiplying a number by zero is an idempotent operation. 5 × 0 is zero, but 5 × 0 × 0 is also zero. Once you multiply a number by zero, you can keep multiplying it by zero indefinitely and get the same result: zero. HTTP DELETE effectively multiplies a resource by zero. Multiplying by 1 is a safe operation, the way HTTP GET is supposed to be safe. You can multiply a number by 1 all day long, and nothing will change. Every safe operation is also idempotent. 36 | Chapter 3: Resources and Representations POST-to-Append POST is the other HTTP method you’ve surely used before. The POST method has two jobs, which I’ll cover separately. The first is POST-to-append, in which sending a POST request to a resource creates a new resource underneath it. When a client sends a POST- to-append request, it sends a representation of the resource it wants to create in the request’s entity-body. I used POST-to-append in Chapter 2 to add a new post to the microblog API. Since I deleted that post while demonstrating DELETE, let’s create a new one: POST /api/ HTTP/1.1 Content-Type: application/vnd.collection+json { "template" : { "data" : [ {"name" : "text", "value" : "testing"} ] } } The most common response code to a POST-to-append request is 201 (Created). It lets the client know that a new resource was created. The Location header lets the client know the URL to this new resource. Another common response code is 202 (Accept ed), which means that the server intends to create a new resource based on the given representation, but hasn’t actually created it yet. The POST method is neither safe nor idempotent. If I send this POST request five times, I’ll probably end up with five new microblog posts, each with the same text but a slightly different date_created. That’s POST-to-append. But you’ve probably used POST for all sorts of things other than “create a new resource.” That’s the other job of POST. That’s called overloaded POST, and I’ll talk about it later in this chapter. PUT A PUT request is a request to modify resource state. The client takes the representation it got from a GET request, modifies it, and sends it back as the payload of a PUT request. Here, I’m going to modify the text of a microblog post (I want the value of the text field to be the string tasting, instead of whatever it was before): PUT /api/q1w2e HTTP/1.1 Content-Type: application/vnd.collection+json { "template" : { "data" : [ The Protocol Semantics of HTTP | 37 {"name" : "text", "value" : "tasting"} ] } } The server is free to reject a PUT request because the entity-body doesn’t make sense, because the entity-body tries to change a bit of resource state the server considers read- only, or really for any reason at all. If the server decides to accept a PUT request, the server changes the resource state to match what the client says in the representation, and usually sends either 200 (OK) or 204 (No Content). PUT is idempotent, just like DELETE. If you send the same PUT request 10 times, the result is the same as if you’d only sent it once. The client can also use PUT to create a new resource, if it knows the URL where the new resource should live. In the following hypothetical example, I’m creating a new microblog post, and I happen to know the URL of the new post: PUT /api/a1s2d3 Content-Type: application/vnd.collection+json { "template" : { "data" : [ {"name" : "text", "value" : "Created."} ] } } How is the client supposed to construct that magical URL? We’ll look at some possi‐ bilities, Chapter 4. For now, just note that PUT is an idempotent operation even when you use it to create a new resource. If I send that PUT request five times, it won’t create five posts with the same text (the way five POST requests might). PATCH Representations can get really big. “Modify the representation and PUT it back” is a simple rule, but if you just want to change one little bit of resource state, it can be pretty wasteful. The PUT rule can also lead to unintentional conflicts with other users who are modifying the same document. It would be nice if you could just send the server the parts of the document you want to change. The PATCH method allows for this. Instead of PUTting a full representation, you can create a special “diff” representation and send it to the server as the payload of a PATCH request. RFC 5261 describes a patch format for XML documents, and RFC 6902 de‐ scribes a similar format for JSON documents: PATCH /my/data HTTP/1.1 Host: example.org 38 | Chapter 3: Resources and Representations Content-Length: 326 Content-Type: application/json-patch+json If-Match: "abc123" [ { "op": "test", "path": "/a/b/c", "value": "foo" }, { "op": "remove", "path": "/a/b/c" }, { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] }, { "op": "replace", "path": "/a/b/c", "value": 42 }, { "op": "move", "from": "/a/b/c", "path": "/a/b/d" }, { "op": "copy", "from": "/a/b/d", "path": "/a/b/e" } ] The best response codes for a successful PATCH are the same as for PUT and DELETE: 200 (OK) if the server wants to send data (such as an updated representation of the resource) along with its response, and 204 (No Content) if the server just wants to indicate success. PATCH is neither safe nor idempotent. A PATCH request might turn out to be idem‐ potent, so that if you accidentally apply the same patch twice to the same document, you get an error the second time. But that’s not in the standard. As far as PATCH’s protocol semantics are concerned, it’s an unsafe operation, like POST. Remember that PATCH is not defined in the HTTP specification. It’s an extension de‐ signed specifically for web APIs, and it’s relatively recent (RFC 5789 was published in 2010). This means that tool support for PATCH, and for the diff documents it uses, is not as good as the support for PUT. LINK and UNLINK LINK and UNLINK manage the hypermedia links between resources. To understand these methods, you must understand hypermedia and link relations, so I’m going to defer a detailed discussion to Chapter 11. I’ll just show some simple examples here. Here’s an UNLINK request that removes the link between a story (identified by http:// www.example.com/story) and its author (identified by http://www.example.com/~om‐ jennyg): UNLINK /story HTTP/1.1 Host: www.example.com Link: ;rel="author" And here’s a LINK request that declares some other resource (identified by http:// www.example.com/~drmilk) to be the author of the story resource: LINK /story HTTP/1.1 Host: www.example.com Link: ;rel="author" The Protocol Semantics of HTTP | 39 LINK and UNLINK are idempotent, but not safe. These methods are defined in an Internet-Draft (“snell-link-method”), and until that draft is approved as an RFC, tool support for them will be even worse than for PATCH. HEAD HEAD is a safe method, just like GET. In fact, it’s best to think of HEAD as a lightweight version of GET. The server is supposed to treat a HEAD request exactly the same as a GET request, but it’s not supposed to send a an entity-body—only the HTTP status code and the headers: HEAD /api/ HTTP/1.1 Accept: application/vnd.collection+json HTTP/1.1 200 OK Content-Type: application/vnd.collection+json ETag: "dd9b7c436ab247a7b69f355f2d57994c" Last-Modified: Thu, 24 Jan 2013 18:40:42 GMT Date: Thu, 24 Jan 2013 19:14:23 GMT Connection: keep-alive Transfer-Encoding: chunked Using HEAD instead of GET may not save any time (the server still has to generate all the appropriate HTTP headers), but it will definitely save bandwidth. OPTIONS OPTIONS is a primitive discovery mechanism for HTTP. The response to an OPTIONS request contains the HTTP Allow header, which lays out which HTTP methods the resource supports. Here’s an OPTIONS request to the microblog post I created in the PUT example: OPTIONS /api/a1s2d3 HTTP/1.1 Host: www.youtypeitwepostit.com 200 OK Allow: GET PUT DELETE HEAD OPTIONS Now I know something about the HTTP requests I can make next. I can GET a repre‐ sentation of this resource, modify it with PUT, or delete it with DELETE. This resource supports HEAD and (of course) OPTIONS, but it doesn’t understand the PATCH ex‐ tension, or LINK or UNLINK. OPTIONS is a good idea, but almost nobody uses it. Well-designed APIs advertise a resource’s capabilities by serving hypermedia documents (see Chapter 4) in response to GET requests. The links and forms in those documents explain what HTTP requests a client can make next. Poorly designed APIs use human-readable documentation to ex‐ plain which HTTP requests a client can make. 40 | Chapter 3: Resources and Representations Overloaded POST Now it’s time to reveal the skeleton in the HTTP closet. The HTTP POST method has a dirty secret, one you’ve certainly encountered if you’ve ever worked in web develop‐ ment. POST is not solely used to create new resources. On the Web we surf with our browsers, HTTP POST is used to convey any kind of change. It’s PUT, DELETE, PATCH, LINK, and UNLINK all rolled into one. Here’s an HTML form you might see on the Web. The purpose of the form is to edit a previously published blog post: In terms of protocol semantics, this operation—“edit this blog post”—sounds like a PUT request. But an HTML form can’t trigger a PUT request. The HTML data format doesn’t allow it. So we use POST instead. This is completely legal. The HTTP specification says that POST can be used for: Providing a block of data, such as the result of submitting a form, to a data-handling process That “data-handling process” can be anything. It’s legal to send any data whatsoever as part of a POST request, for any purpose at all. The definition is so vague that a POST request really has no protocol semantics at all. POST doesn’t really mean “create a new resource”; it means “whatever!” I call this “whatever!” usage of POST overloaded POST. Because an overloaded POST request has no protocol semantics, you can only understand it in terms of its application semantics. I’ll have a lot to say about application semantics in the next few chapters, so for now I’ll just point them out in this HTML form. The application semantics in that form are the CSS class attached to the submit button (edit-post) and the human-readable label attached to the button (“Edit this blog post.”) Those two strings are not much to work from. Until recently, application semantics were so poorly understood that I recommended not using overloaded POST at all. But if you follow the advice I give in Chapter 8, you can use a profile to reliably communicate application semantics to your clients. It won’t be as reliable as the protocol semantics— every HTTP client ever made knows what GET means—but you’ll be able to do it. The Protocol Semantics of HTTP | 41 Since an overloaded POST request can do anything at all, the POST method is neither safe nor idempotent. One particular overloaded POST request may turn out to be safe, but as far as HTTP is concerned, POST is unsafe. Which Methods Should You Use? A RESTful system is made up of independent components: servers, clients, caches, proxies, caching proxies, and so on. These components were created by different people, they’ve never heard of each other before they start talking, and they can only commu‐ nicate by passing documents back and forth over HTTP (or some similar protocol). It’s essential that everyone agree on a set of protocol semantics ahead of time, or the com‐ ponents won’t understand each other. The protocol semantics of HTTP are mostly defined by the HTTP methods. But there’s a lot of redundancy in these methods. PUT can substitute for PATCH. GET can do the job of HEAD. POST can substitute for anything. Do we really need all these methods? There’s no official set of protocol semantics. We can have a lot of fun arguing over which HTTP methods are the best, but it really comes down to membership in a community. When you choose the HTTP methods you’re going to use, you choose a community of clients and other components that understand those methods. The methods I recommend for use in most web APIs are GET, POST, PUT, DELETE, and PATCH. But I can think of a lot of cases where I’d recommend different methods: • Before 2008, the PATCH method didn’t exist. Back then, the method set I recom‐ mended for web APIs was GET, POST, PUT, and DELETE. • In 1997, the first version of the HTTP 1.1 specification (RFC 2068) defined the HTTP methods LINK and UNLINK. In 1999, these methods were removed from the final specification (RFC 2616), because no one was using them. LINK and UNLINK were part of HTTP’s official protocol semantics for about two years. Then they went away. Since these methods would be useful in a lot of APIs, the Internet-Draft “snell-link-method” is trying to bring them back. • The WebDAV standard (specified in RFC 4918, and covered briefly in Chapter 11) defines seven new HTTP methods for use in APIs that treat HTTP resources as though they were files on a filesystem. These methods include COPY, MOVE, and LOCK. • When we humans surf around on our web browsers, we completely ignore most of the methods defined in the HTTP specification, and get by with just GET and POST. That’s because the protocol semantics of HTML documents only allow for GET and POST. 42 | Chapter 3: Resources and Representations • The CoAP protocol (described in Chapter 13) defines the methods GET, POST, PUT, and DELETE. These methods were named after HTTP methods, but they mean slightly different things, because CoAP is not HTTP. If you want an API entirely described by HTML documents, then your protocol se‐ mantics are limited to GET and POST. If you want to speak to filesystem GUI applica‐ tions like Microsoft’s Web Folders, you’ll be using HTTP plus the WebDAV extensions. If you need to talk to a wide variety of HTTP caches and proxies, you should stay away from PATCH and other methods not defined in RFC 2616. Some communities are bigger than others. When you go off the path and make up your own protocol semantics, you’re isolating yourself in a community of one. Which Methods Should You Use? | 43 CHAPTER 4 Hypermedia The story so far: URLs identify resources. A client makes HTTP requests to those URLs. A server sends representations in response, and over time the client builds up a picture of the resource state, as seen through the representations. Eventually the client makes that fateful PUT or POST or PATCH request, sending a representation back to the server and modifying resource state. Look closer, and you’ll see a question that hasn’t been answered: how does the client know which requests it can make? There are infinitely many URLs. How does a client know which URLs have representations behind them and which ones will give a 404 error? Should the client send an entity-body with its POST request? If so, what should the entity-body look like? HTTP defines a set of protocol semantics, but which subset of those semantics does this web server support on this URL right now? The missing piece of the puzzle is hypermedia. Hypermedia connects resources to each other, and describes their capabilities in machine-readable ways. Properly used, hyper‐ media can solve—or at least mitigate—the usability and stability problems found in today’s web APIs. Like REST, hypermedia isn’t a single technology described by a standards document somewhere. Hypermedia is a strategy, implemented in different ways by dozens of technologies. I’ll cover several hypermedia standards in the next three chapters, and a whole lot more in Chapter 10. It’s up to you to choose the technologies that fit your business requirements. The hypermedia strategy always has the same goal. Hypermedia is a way for the server to tell the client what HTTP requests the client might want to make in the future. It’s a menu, provided by the server, from which the client is free to choose. The server knows what might happen, but the client decides what actually happens. There’s nothing new here. The World Wide Web works this way, and we all take it for granted that it should work this way. Anything else would be an unusable throwback to 45 1. There are two HTML specifications you should know about: the HTML 4 spec and the HTML 5 spec. Both are open standards produced by the W3C. HTML 4 has been stable for over 10 years; HTML 5 is a work in progress. 2. That’s in section 12.1.1 of the HTML 4 specification. the 1980s. But in the world of APIs, hypermedia is a confusing and controversial topic. That’s why today’s APIs are terrible at managing change. In this chapter, I want to dispel the mystery of hypermedia, so you can create APIs that have some of the flexibility of the Web. HTML as a Hypermedia Format You’re probably already familiar with HTML,1 so let’s start with an HTML example. Here’s an HTML tag: See the latest messages This tag is a simple hypermedia control. It’s a description of an HTTP request your browser might make in the near future. An tag is a signal to your browser that it can make an HTTP GET request that would look something like this: GET /messages HTTP/1.1 Host: www.youtypeitwepostit.com The HTML standard says that when the user activates a link, the user “visits” the resource on the other end of the link.2 In practice, this means fetching a representation of the resource and displaying it in the browser window, replacing the original representation (the one that included the link). Of course, that doesn’t happen automatically. Nothing will happen until the user clicks on the link. An tag is a promise from the web server that a certain URL names a resource you can visit. If you sent a GET request to a URL you made up, such as http://www.youtypeitwepostit.com/give-me-the-messages? please=true, you’d probably just get a 404 error. Compare the tag to another of HTML’s hypermedia controls, the tag: The tag also describes an HTTP request your browser might make in the near future, but there’s no implication that you’re moving from one document to another. Instead, the representation of the linked resource is supposed to be embedded as an image in the current document. When your browser finds an tag, it makes the request for the image automatically, without asking you to click on anything. Then it 46 | Chapter 4: Hypermedia incorporates the representation in the document you’re viewing, again without asking your permission. Let’s look at a more complex hypermedia control—an HTML form:
This form describes a request to the URL http://www.youtypeitwepostit.com/ messages/. That’s the same URL I used for the
tag. But the tag described a GET request, and this form describes a POST request. This form doesn’t just give you the URL and send you off to make a POST request. There are also two controls—a text field and a submit button—which are rendered as GUI elements in a web browser. When you click the submit button, the value you entered in the text field and the value on the button are transformed into a representation, according to rules set down in the HTML specification. Those rules say the media type of the representation will be ap plication/x-www-form-urlencoded, and it will look something like this: message=Hello%21&submit=Post Putting it all together, that
tag tells your browser that it can make a POST request that looks something like this: POST /messages HTTP/1.1 Host: www.youtypeitwepostit.com Content-Type: application/x-www-form-urlencoded message=Hello%21&submit=Post As with the tag, the server’s guiding you, but its hand is pretty light. If you don’t want to fill out this form, you can ignore it. If you do fill out the form, you can put whatever you want in the message field (although the server might reject certain values). The tag is the server telling you that, of all the possible POST requests you might make, there’s one type of request that’s likely to result in something useful. That’s a POST to /messages, which includes a form-encoded entity-body that includes a value for message. Here’s one more tag: This form also has a text box you’re supposed to fill out, but the form is telling you to make a GET request, and GET requests don’t include an entity-body. Instead, the data HTML as a Hypermedia Format | 47 you type into that text box gets incorporated into the request URL—again, according to rules laid out in the HTML specification. If you fill out this form, the HTTP request your browser makes will look something like this: GET /messages/?query=rest HTTP/1.1 Host: www.youtypeitwepostit.com To sum up, the familiar HTML controls allow the server to describe four kinds of HTTP requests. • The
tag describes a GET request for one specific URL, which is made only if the user triggers the control. • The tag describes a GET request for one specific URL, which happens auto‐ matically, in the background. • The
tag with method="POST" describes a POST request to one specific URL, with a custom entity-body constructed by the client. The request is only made if the user triggers the control. • The tag with method="GET" describes a GET request to a custom URL con‐ structed by the client. The request is only made if the user triggers the control. HTML also defines some more exotic hypermedia controls, and other data formats may define controls that are stranger still. All of them fall under the formal definition of hypermedia given in the Fielding dissertation: Hypermedia is defined by the presence of application control information embedded within, or as a layer above, the presentation of information. The World Wide Web is full of HTML documents, and the documents are full of things people like to read—prices, statistics, personal messages, prose, and poetry. But all of those things fall under presentation of information. In terms of presentation of infor‐ mation, the Web isn’t much different from a printed book. It’s the application control information that distinguishes an HTML document from a book. I’m talking about the hypermedia controls that people interact with all the time, but rarely examine closely. The tags that tell the browser to embed certain images, the tags that transport the end user to another part of the Web, and the