Under Construction: The book you’re reading is still under development. As part of our Beta book program, we’re releasing ß this copy well before a normal book would be released. That way you’re able to get this content a couple of months before it’s available in finished form, and we’ll get feedback to make the book even better. The idea is that everyone wins! Be warned: The book has not had a full technical edit, so it will contain errors. It has not been copyedited, so it will be full of typos, spelling mistakes, and the occasional creative piece of grammar. And there’s been no effort spent doing layout, so you’ll find bad page breaks, over-long code lines, incorrect hyphen- ation, and all the other ugly things that you wouldn’t expect to see in a finished book. It also doesn't have an index. We can’t be held liable if you use this book to try to create a spiffy application and you somehow end up with a strangely shaped farm implement instead. Despite all this, we think you’ll enjoy it! Download Updates: Throughout this process you’ll be able to get updated ebooks from your account at pragprog.com/my_account. When the book is com- plete, you’ll get the final version (and subsequent updates) from the same ad- dress. Send us your feedback: In the meantime, we’d appreciate you sending us your feedback on this book at pragprog.com/titles/dswdcloj3/errata, or by using the links at the bottom of each page. Thank you for being part of the Pragmatic community! The Pragmatic Bookshelf Web Development with Clojure, Third Edition Build Large, Maintainable Web Applications Interactively Dmitri Sotnikov Scot Brown The Pragmatic Bookshelf Raleigh, North Carolina 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 The Pragmatic Programmers, LLC was aware of a trademark claim, the designations have been printed in initial capital letters or in all capitals. The Pragmatic Starter Kit, The Pragmatic Programmer, Pragmatic Programming, Pragmatic Bookshelf, PragProg and the linking g device are trade- marks of The Pragmatic Programmers, LLC. Every precaution was taken in the preparation of this book. However, the publisher assumes no responsibility for errors or omissions, or for damages that may result from the use of information (including program listings) contained herein. For our complete catalog of hands-on, practical, and Pragmatic content for software devel- opers, please visit https://pragprog.com. For sales, volume licensing, and support, please contact [email protected]. For international rights, please contact [email protected]. Copyright © 2021 The Pragmatic Programmers, LLC. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form, or by any means, electronic, mechanical, photocopying, recording, or otherwise, without the prior consent of the publisher. ISBN-13: 978-1-68050-682-2 Encoded using the finest acid-free high-entropy binary digits. Book version: B17.0—March 12, 2021 Contents Changes in the Beta Release . . . . . . . . . vii Acknowledgments . . . . . . . . . . . xi Introduction . . . . . . . . . . . . xiii 1. Getting Your Feet Wet. . . . . . . . . . . 1 Set Up Your Environment 1 Managing Projects with Leiningen 2 Build Your First Web App 4 Refine Your App 9 What You’ve Learned 26 2. Luminus Web Stack . . . . . . . . . . . 29 Route Requests with Ring 29 Extend Ring 37 Define the Routes with Reitit 42 HTML Templating Using Selmer 46 What You’ve Learned 54 3. Luminus Architecture . . . . . . . . . . 55 Manage the Project 55 Think in Terms of Application Components 57 Managing Stateful Components 67 What You’ve Learned 70 4. Introducing Clojurescript . . . . . . . . . 71 Understand ClojureScript 71 Add ClojureScript Support 73 Build the UI with Reagent 77 Managing State with Re-Frame 94 What You’ve Learned 98 Contents • iv 5. Setting Up for Success . . . . . . . . . . 99 Services 100 ClojureScript Development Tools 117 Embracing Re-Frame 130 Multi-User With Websockets 138 Upgrading to Sente 143 Events and Effects in Re-Frame 151 What You’ve Learned 156 6. Planning Our Application . . . . . . . . . 159 What’s in our MVP? 159 The Elephant in the Room 162 Data Modelling 165 Adding User Management 166 What you’ve learned 184 7. Account Management . . . . . . . . . . 185 Authorship 185 Add Author’s Posts Page 196 Account Customization 217 Account Settings 250 What You’ve Learned 260 8. Social Interaction . . . . . . . . . . . 261 Improving Posts 261 Curating Posts 316 What you’ve learned 328 9. Deployment . . . . . . . . . . . . 329 Unit Tests 329 Package the Application 338 What You’ve Learned 343 10. Exercises . . . . . . . . . . . . . 345 How to Read this Chapter 345 Code Quality 346 Feature Enhancements 350 What You’ve Learned 360 A1. Clojure Primer . . . . . . . . . . . . 361 A Functional Perspective 361 Data Types 363 Contents • v Using Functions 364 Anonymous Functions 364 Named Functions 365 Higher-Order Functions 367 Closures 368 Threading Expressions 369 Being Lazy 369 Structuring the Code 370 Destructuring Data 371 Namespaces 372 Dynamic Variables 374 Polymorphism 375 What About Global State? 377 Writing Code That Writes Code for You 378 The Read-Evaluate-Print Loop 380 Calling Out to Java 380 Calling Methods 381 Reader Conditionals 382 Summary 383 A2. Editor Configuration . . . . . . . . . . 385 Why is Editor Integration So Important? 385 General Configuration Tips 387 VSCode + Calva 387 IntelliJ IDEA + Cursive 387 Emacs + Cider 387 Vim 388 A3. Working with EDN and Transit . . . . . . . . 389 EDN 389 Transit 390 A4. Database Access . . . . . . . . . . . 393 Work with Relational Databases 393 Use HugSQL 399 Generate Reports 403 What You’ve Learned 412 Contents • vi A5. Writing RESTful Web Services with Liberator . . . . 413 Using Liberator 413 Defining Resources 414 Putting It All Together 418 A6. Leiningen Templates . . . . . . . . . . 425 What’s in a Template 425 Changes in the Beta Release Beta 17, March 5, 2021 Updated all library versions. Migrated to next.jdbc. Restructured test/ directory to reflect common convention. Content complete and heading to copyediting and indexing. Beta 16, December 23, 2020 Fixed typo in Chapter 5. Added reference to first introduction of :messages/filter Added Editor Configuration Appendix Added Leiningen Templates Appendix Added Encoding Appendix Beta 15, December 15, 2020 Add Chapter 10, Exercises. Add ClojureScript Testing to Chapter 9 Reference ClojureScript Testing section from Chapter 5. Remove outdated authorq tags Beta 14, December 08, 2020 Address typo in Chapter 7. Address common issue with ‘create-migration‘ where readers don’t run ‘start‘ first. report erratum • discuss Changes in the Beta Release • viii Add instructions on how to get source code Address reloading issue. Briefly explain reagent closing over arguments. Add logout route implementation. Update package.json. Beta 13, November 09, 2020 Add Chapter 9: Deployment Remove LookBehind from Regular Expressions in Chapter 8 to improve browser compatibility Beta 12, October 27, 2020 Add Chapter 8: Social Interaction Clarify usage of vars in Chapter 2 Remove broken vars in front-end controllers Beta 11 Skipped. Beta 10, August 18, 2020 Fix image-uploader to clear stale state. In Account Management > Account Customization Fix nil auth handling Fix reitit route reloading Pull li wrapper out of message component to allow better reuse Update reagent to 0.10.0 Update Re-frame to 1.0.0 Beta 9, July 21, 2020 Fixed code typo in profile page which caused Update Profile to be incorrectly disabled in Account Management > Account Customization Added missing require of clojure.java.io to REPL example in Account Manage- ment > Account Customization report erratum • discuss