calibre.leishi.io
Open in
urlscan Pro
2a06:98c1:3121::c
Public Scan
URL:
https://calibre.leishi.io/read/76/pdf
Submission: On February 07 via manual from IN — Scanned from NL
Submission: On February 07 via manual from IN — Scanned from NL
Form analysis
0 forms found in the DOMText Content
Thumbnails Document Outline Attachments Layers Foreword Preface What Is This Book About Cloud-native applications Working in a team Who Is This Book For Getting Started Installing The Rust Toolchain Compilation Targets Release Channels What Toolchains Do We Need? Project Setup IDEs Rust-analyzer IntelliJ Rust What Should I Use? Inner Development Loop Faster Linking cargo-watch Continuous Integration CI Steps Tests Code Coverage Linting Formatting Security Vulnerabilities Ready-to-go CI Pipelines Building An Email Newsletter Our Driving Example Problem-based Learning Course-correcting What Should Our Newsletter Do? Capturing Requirements: User Stories Working In Iterations Coming Up Sign Up A New Subscriber Our Strategy Choosing A Web Framework Our First Endpoint: A Basic Health Check Wiring Up actix-web Anatomy Of An actix-web Application Server - HttpServer Application - App Endpoint - Route Runtime - tokio Implementing The Health Check Handler Our First Integration Test How Do You Test An Endpoint? Where Should I Put My Tests? Changing Our Project Structure For Easier Testing Implementing Our First Integration Test Polishing Clean Up Choosing A Random Port Refocus Working With HTML Forms Refining Our Requirements Capturing Our Requirements As Tests Parsing Form Data From A POST Request Extractors Form And FromRequest Serialisation In Rust: serde Putting Everything Together Storing Data: Databases Choosing A Database Choosing A Database Crate Compile-time Safety Query Interface Async Support Summary Our Pick: sqlx Integration Testing With Side-effects Database Setup Docker Database Migrations Writing Our First Query Sqlx Feature Flags Configuration Management Connecting To Postgres Our Test Assertion Updating Our CI Pipeline Persisting A New Subscriber Application State In actix-web actix-web Workers The Data Extractor The INSERT Query Updating Our Tests Test Isolation Summary Telemetry Unknown Unknowns Observability Logging The log Crate actix-web's Logger Middleware The Facade Pattern Instrumenting POST /subscriptions Interactions With External Systems Think Like A User Logs Must Be Easy To Correlate Structured Logging The tracing Crate Migrating From log To tracing tracing's Span Instrumenting Futures tracing's Subscriber tracing-subscriber tracing-bunyan-formatter tracing-log Removing Unused Dependencies Cleaning Up Initialisation Logs For Integration Tests Cleaning Up Instrumentation Code - tracing::instrument Protect Your Secrets - secrecy Request Id Leveraging The tracing Ecosystem Summary Going Live We Must Talk About Deployments Choosing Our Tools Virtualisation: Docker Hosting: DigitalOcean A Dockerfile For Our Application Dockerfiles Build Context Sqlx Offline Mode Running An Image Networking Hierarchical Configuration Database Connectivity Optimising Our Docker Image Docker Image Size Caching For Rust Docker Builds Deploy To DigitalOcean Apps Platform Setup App Specification How To Inject Secrets Using Environment Variables Connecting To Digital Ocean's Postgres Instance Environment Variables In The App Spec One Last Push Reject Invalid Subscribers #1 Requirements Domain Constraints Security Constraints First Implementation Validation Is A Leaky Cauldron Type-Driven Development Ownership Meets Invariants AsRef Panics Error As Values - Result Converting parse To Return Result Insightful Assertion Errors: claim Unit Tests Handling A Result match The ? Operator 400 Bad Request The Email Format The SubscriberEmail Type Breaking The Domain Sub-Module Skeleton Of A New Type Property-based Testing How To Generate Random Test Data With fake quickcheck Vs proptest Getting Started With quickcheck Implementing The Arbitrary Trait Payload Validation Refactoring With TryFrom Summary Reject Invalid Subscribers #2 Confirmation Emails Subscriber Consent The Confirmation User Journey The Implementation Strategy EmailClient, Our Email Delivery Component How To Send An Email Choosing An Email API The Email Client Interface How To Write A REST Client Using reqwest reqwest::Client Connection Pooling How To Reuse The Same reqwest::Client In actix-web Configuring Our EmailClient How To Test A REST Client HTTP Mocking With wiremock wiremock::MockServer wiremock::Mock The Intent Of A Test Should Be Clear Mock expectations First Sketch Of EmailClient::send_email reqwest::Client::post JSON body Authorization Token Executing The Request Tightening Our Happy Path Test Refactoring: Avoid Unnecessary Memory Allocations Dealing With Failures Error Status Codes Timeouts Refactoring: Test Helpers Refactoring: Fail fast Skeleton And Principles For A Maintainable Test Suite Why Do We Write Tests? Why Don't We Write Tests? Test Code Is Still Code Our Test Suite Test Discovery One Test File, One Crate Sharing Test Helpers Sharing Startup Logic Extracting Our Startup Code Testing Hooks In Our Startup Logic Build An API Client Summary Refocus Zero Downtime Deployments Reliability Deployment Strategies Naive Deployment Load Balancers Rolling Update Deployments Digital Ocean App Platform Database Migrations State Is Kept Outside The Application Deployments And Migrations Multi-step Migrations A New Mandatory Column Step 1: Add As Optional Step 2: Start Using The New Column Step 3: Backfill And Mark As NOT NULL A New Table Sending A Confirmation Email A Static Email Red test Green test A Static Confirmation Link Red Test Green Test Refactor Pending Confirmation Red test Green Test Skeleton of GET /subscriptions/confirm Red Test Green Test Connecting The Dots Red Test Green Test Refactor Subscription Tokens Red Test Green Test Database Transactions All Or Nothing Transactions In Postgres Transactions In Sqlx Summary Error Handling What Is The Purpose Of Errors? Internal Errors Enable The Caller To React Help An Operator To Troubleshoot Errors At The Edge Help A User To Troubleshoot Summary Error Reporting For Operators Keeping Track Of The Error Root Cause The Error Trait Trait Objects Error::source Errors For Control Flow Layering Modelling Errors as Enums The Error Type Is Not Enough Removing The Boilerplate With thiserror Avoid ``Ball Of Mud'' Error Enums Using anyhow As Opaque Error Type anyhow Or thiserror? Who Should Log Errors? Summary Naive Newsletter Delivery User Stories Are Not Set In Stone Do Not Spam Unconfirmed Subscribers Set Up State Using The Public API Scoped Mocks Green Test All Confirmed Subscribers Receive New Issues Composing Test Helpers Implementation Strategy Body Schema Test Invalid Inputs Fetch Confirmed Subscribers List Send Newsletter Emails context Vs with_context Validation Of Stored Data Responsibility Boundaries Follow The Compiler Remove Some Boilerplate Limitations Of The Naive Approach Summary Securing Our API Authentication Drawbacks Something They Know Something They Have Something They Are Multi-factor Authentication Password-based Authentication Basic Authentication Extracting Credentials Password Verification - Naive Approach Password Storage No Need To Store Raw Passwords Using A Cryptographic Hash Preimage Attack Naive Dictionary Attack Dictionary Attack Argon2 Salting PHC String Format Do Not Block The Async Executor Tracing Context Is Thread-Local User Enumeration Is it safe? Transport Layer Security (TLS) Password Reset Interaction Types Machine To Machine Client Credentials via OAuth2 Person Via Browser Federated Identity Machine to machine, on behalf of a person Interlude: Next Steps Login Forms Serving HTML Pages Login HTML Forms Redirect On Success Processing Form Data Building An authentication Module Rejecting Invalid Credentials Contextual Errors Naive Approach Query Parameters Cross-Site Scripting (XSS) Message Authentication Codes Add An HMAC Tag To Protect Query Parameters Verifying The HMAC Tag Error Messages Must Be Ephemeral What Is A Cookie? An Integration Test For Login Failures How To Set A Cookie In actix-web An Integration Test For Login Failures - Part 2 How To Read A Cookie In actix-web How To Delete A Cookie In actix-web Cookie Security actix-web-flash-messages Sessions Session-based Authentication Session Store Choosing A Session Store Postgres Redis actix-session Redis In Our Development Setup Redis On Digital Ocean Admin Dashboard Redirect On Login Success Session A Typed Interface To Session Reject Unauthenticated Users Seed Users Database Migration Password Reset Form Skeleton Unhappy Path: New Passwords Do Not Match Unhappy Path: The Current Password Is Invalid Unhappy Path: The New Password Is Too Short Logout Happy Path: The Password Was Changed Successfully Refactoring How To Write An actix-web Middleware Summary Fault-tolerant Workflows POST /admin/newsletters - A Refresher Our Goal Failure Modes Invalid Inputs Network I/O Postgres Postmark - API Errors Application Crashes Author Actions Idempotency: An Introduction Idempotency In Action: Payments Idempotency Keys Concurrent Requests Requirements As Tests #1 Implementation Strategies Stateful Idempotency: Save And Replay Stateless Idempotency: Deterministic Key Generation Time Is a Tricky Beast Making A Choice Idempotency Store Which Database Should We Use? Schema Save And Replay Read Idempotency Key Retrieve Saved Responses Save Responses MessageBody and HTTP Streaming Array Of Composite Postgres Types Plug It In Concurrent Requests Requirements As Tests #2 Synchronization Transaction Isolation Levels Dealing With Errors Distributed Transactions Backward Recovery Forward Recovery Asynchronous Processing newsletter_issues issue_delivery_queue POST /admin/newsletters Email Processing Worker loop Launching Background Workers Updating The Test Suite Epilogue Previous Next Highlight all Match case Whole words Presentation Mode Open Current View Go to First Page Go to Last Page Rotate Clockwise Rotate Counterclockwise Text Selection Tool Hand Tool Vertical Scrolling Horizontal Scrolling Wrapped Scrolling No Spreads Odd Spreads Even Spreads Document Properties… Toggle Sidebar Find Previous Next of 433 Presentation Mode Open Current View Tools Zoom Out Zoom In Automatic Zoom Actual Size Page Fit Page Width 50% 75% 100% 125% 150% 200% 300% 400% PRODUCTIONPRODUCTIONAN OPINIONATED INTRODUCTION TO BACKEND DEVELOPMENTLuca PalmieriZERO TOIN RUSTSold tokartik.ynwa@gmail.com ContentsForeword9Preface10What Is This Book About. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10Cloud-native applications. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10Working in a team. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11Who Is This Book For. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .111 Getting Started131.1 Installing The Rust Toolchain. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .131.1.1 Compilation Targets. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .131.1.2 Release Channels. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .131.1.3 What Toolchains Do We Need?. . . . . . . . . . . . . . . . . . . . . . . . . . .141.2 Project Setup. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .141.3 IDEs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .151.3.1 Rust-analyzer. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .151.3.2 IntelliJ Rust. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .151.3.3 What Should I Use?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .151.4 Inner Development Loop. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .151.4.1 Faster Linking. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .161.4.2cargo-watch. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .161.5 Continuous Integration. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .171.5.1 CI Steps. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .181.5.1.1 Tests. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .181.5.1.2 Code Coverage. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .181.5.1.3 Linting. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .181.5.1.4 Formatting. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .191.5.1.5 Security Vulnerabilities. . . . . . . . . . . . . . . . . . . . . . . . . .191.5.2 Ready-to-go CI Pipelines. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .202 Building An Email Newsletter212.1 Our Driving Example. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .212.1.1 Problem-based Learning. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .212.1.2 Course-correcting. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .212.2 What Should Our Newsletter Do?. . . . . . . . . . . . . . . . . . . . . . . . . . . . .212.2.1 Capturing Requirements: User Stories. . . . . . . . . . . . . . . . . . . . . . .222.3 Working In Iterations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .222.3.1 Coming Up. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .233 Sign Up A New Subscriber243.1 Our Strategy. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .243.2 Choosing A Web Framework. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .243.3 Our First Endpoint: A Basic Health Check. . . . . . . . . . . . . . . . . . . . . . . .253.3.1 Wiring Upactix-web. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .253.3.2 Anatomy Of Anactix-webApplication. . . . . . . . . . . . . . . . . . . . . .263.3.2.1 Server -HttpServer. . . . . . . . . . . . . . . . . . . . . . . . . . . .263.3.2.2 Application -App. . . . . . . . . . . . . . . . . . . . . . . . . . . . .263.3.2.3 Endpoint -Route. . . . . . . . . . . . . . . . . . . . . . . . . . . . .273.3.2.4 Runtime -tokio. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .273.3.3 Implementing The Health Check Handler. . . . . . . . . . . . . . . . . . . . .303.4 Our First Integration Test. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .323.4.1 How Do You Test An Endpoint?. . . . . . . . . . . . . . . . . . . . . . . . . .323.4.2 Where Should I Put My Tests?. . . . . . . . . . . . . . . . . . . . . . . . . . .333.4.3 Changing Our Project Structure For Easier Testing. . . . . . . . . . . . . . . .343.5 Implementing Our First Integration Test. . . . . . . . . . . . . . . . . . . . . . . . . .363.5.1 Polishing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .391 More Information Less Information Close Enter the password to open this PDF file. Cancel OK File name: - File size: - Title: - Author: - Subject: - Keywords: - Creation Date: - Modification Date: - Creator: - PDF Producer: - PDF Version: - Page Count: - Page Size: - Fast Web View: - Close Preparing document for printing… 0% Cancel