[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-build-rust-rest-api-actix-sqlx-postgres-en":3,"tags-build-rust-rest-api-actix-sqlx-postgres-en":30,"related-lang-build-rust-rest-api-actix-sqlx-postgres-en":41,"related-posts-build-rust-rest-api-actix-sqlx-postgres-en":45,"series-tools-90605034-906b-46b7-a7ff-db3d3b4add1b":82},{"id":4,"title":5,"content":6,"summary":7,"source":8,"source_url":9,"author":10,"image_url":11,"keywords":12,"language":18,"translated_content":10,"views":19,"is_premium":20,"created_at":21,"updated_at":21,"cover_image":11,"published_at":22,"rewrite_status":23,"rewrite_error":10,"rewritten_from_id":24,"slug":25,"category":26,"related_article_id":27,"status":28,"google_indexed_at":29,"x_posted_at":10,"tweet_text":10,"title_rewritten_at":10,"title_original":10,"key_takeaways":10,"topic_cluster_id":10,"embedding":10,"is_canonical_seed":20},"90605034-906b-46b7-a7ff-db3d3b4add1b","Build a Rust REST API with Actix, SQLx, Postgres","\u003Cp>Rust teams keep circling the same stack for backend APIs: \u003Ca href=\"https:\u002F\u002Factix.rs\u002F\" target=\"_blank\" rel=\"noopener\">Actix Web\u003C\u002Fa>, \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Flaunchbadge\u002Fsqlx\" target=\"_blank\" rel=\"noopener\">SQLx\u003C\u002Fa>, and \u003Ca href=\"https:\u002F\u002Fwww.postgresql.org\u002F\" target=\"_blank\" rel=\"noopener\">PostgreSQL\u003C\u002Fa>. That combination is not trendy for its own sake. It is popular because it gives you async handlers, compile-time SQL checks, and a database that can take real traffic without forcing you into a rewrite later.\u003C\u002Fp>\u003Cp>Marcus Chen’s tutorial, which Prism News highlighted this week, makes a simple argument: if you want a production API in Rust, this stack gets you there with fewer surprises than most alternatives. The real work is in the details people usually skip on day one, like pool sizing, migration workflow, and error mapping.\u003C\u002Fp>\u003Ch2>Why this stack keeps winning\u003C\u002Fh2>\u003Cp>The first decision is the web framework. \u003Ca href=\"https:\u002F\u002Factix.rs\u002F\" target=\"_blank\" rel=\"noopener\">Actix Web 4\u003C\u002Fa> is still one of the fastest Rust frameworks in common use, and the comparison point is usually \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Ftokio-rs\u002Faxum\" target=\"_blank\" rel=\"noopener\">Axum\u003C\u002Fa>. Axum is built around the \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Ftokio-rs\u002Ftower\" target=\"_blank\" rel=\"noopener\">Tower\u003C\u002Fa> ecosystem and feels very natural if your team already lives in Tokio middleware. Actix, though, has a longer production track record and a wider set of examples people can copy without translating everything from scratch.\u003C\u002Fp>\n\u003Cfigure class=\"my-6\">\u003Cimg src=\"https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1775153217317-vih7.png\" alt=\"Build a Rust REST API with Actix, SQLx, Postgres\" class=\"rounded-xl w-full\" loading=\"lazy\" \u002F>\u003C\u002Ffigure>\n\u003Cp>That matters because backend teams do not ship benchmarks. They ship systems that survive bad requests, slow queries, and the occasional dependency upgrade that changes runtime behavior. In that context, Actix’s maturity often matters more than a small throughput edge.\u003C\u002Fp>\u003Cp>SQLx makes the database side more interesting. Instead of hiding SQL behind an ORM, it keeps your queries in plain text and checks them at compile time against a live database or a cached offline plan. That gives you real SQL control while still catching typos and schema mismatches before deployment.\u003C\u002Fp>\u003Cul>\u003Cli>Actix Web 4 is the framework in the tutorial, with typed extractors and Tokio integration.\u003C\u002Fli>\u003Cli>Axum 0.8.8 remains the main alternative for teams already invested in Tower.\u003C\u002Fli>\u003Cli>SQLx supports PostgreSQL, MySQL, and SQLite, but its async story is native rather than bolted on.\u003C\u002Fli>\u003Cli>PostgreSQL handles pooled connections and concurrent writes far better than SQLite for most public APIs.\u003C\u002Fli>\u003C\u002Ful>\u003Cp>PostgreSQL is the least controversial part of the stack. SQLite is great for local tools and small apps, but once you need connection pooling, concurrent workers, and a migration history that lives in version control, Postgres is the cleaner choice. If you start with Postgres in Docker locally, your production setup becomes an environment change instead of a redesign.\u003C\u002Fp>\u003Ch2>What the project setup actually looks like\u003C\u002Fh2>\u003Cp>The tutorial’s project setup is refreshingly ordinary, which is a good thing. Your \u003Ccode>Cargo.toml\u003C\u002Fcode> usually pulls in \u003Ccode>actix-web\u003C\u002Fcode>, \u003Ccode>sqlx\u003C\u002Fcode> with the \u003Ccode>postgres\u003C\u002Fcode>, \u003Ccode>runtime-tokio\u003C\u002Fcode>, and \u003Ccode>macros\u003C\u002Fcode> features, plus \u003Ccode>serde\u003C\u002Fcode>, \u003Ccode>dotenvy\u003C\u002Fcode>, \u003Ccode>tracing\u003C\u002Fcode>, and \u003Ccode>tracing-subscriber\u003C\u002Fcode>. The dev tool that matters most is \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Flaunchbadge\u002Fsqlx\u002Fblob\u002Fmain\u002Fsqlx-cli\u002FREADME.md\" target=\"_blank\" rel=\"noopener\">sqlx-cli\u003C\u002Fa>, which handles migrations and the offline query cache.\u003C\u002Fp>\u003Cp>Actix runs on Tokio, and that runtime detail is one of the easiest places to trip. If another crate in your app expects a different Tokio version or runtime setup, the code may compile and still behave badly once the service starts handling real traffic. That is the kind of bug that shows up after the demo, which is exactly why the tutorial spends time on it.\u003C\u002Fp>\u003Cp>The other setup choice that pays off early is logging. Structured logs from \u003Ca href=\"https:\u002F\u002Fdocs.rs\u002Ftracing\u002Flatest\u002Ftracing\u002F\" target=\"_blank\" rel=\"noopener\">tracing\u003C\u002Fa> give you request IDs, spans, and query timing without forcing you to manually thread context through every function call. For a REST API, that is the difference between guessing and knowing why a request slowed down.\u003C\u002Fp>\u003Cul>\u003Cli>\u003Ccode>#[actix_web::main]\u003C\u002Fcode> boots the Tokio runtime for the server.\u003C\u002Fli>\u003Cli>\u003Ccode>web::Data\u003C\u002Fcode> stores shared state such as the Postgres pool.\u003C\u002Fli>\u003Cli>\u003Ccode>web::Json\u003C\u002Fcode>, \u003Ccode>web::Path\u003C\u002Fcode>, and \u003Ccode>web::Query\u003C\u002Fcode> parse inputs before your handler runs.\u003C\u002Fli>\u003Cli>\u003Ccode>sqlx migrate\u003C\u002Fcode> and \u003Ccode>cargo sqlx prepare\u003C\u002Fcode> are part of the workflow, not afterthoughts.\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>The part most tutorials skip\u003C\u002Fh2>\u003Cp>Marcus Chen’s framing is strongest when he gets into the day-two issues. Pool sizing is one of those details that looks boring until it breaks your service. If your pool is too small, requests queue and latency climbs. If it is too large, Postgres becomes the bottleneck and starts rejecting work under load.\u003C\u002Fp>\n\u003Cfigure class=\"my-6\">\u003Cimg src=\"https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1775153216347-95oy.png\" alt=\"Build a Rust REST API with Actix, SQLx, Postgres\" class=\"rounded-xl w-full\" loading=\"lazy\" \u002F>\u003C\u002Ffigure>\n\u003Cp>That is why a starting point such as two connections per async worker thread is only a starting point. You still need to account for your CPU count, your database’s \u003Ccode>max_connections\u003C\u002Fcode>, and the average latency of your queries. The right answer is usually empirical, not theoretical.\u003C\u002Fp>\u003Cblockquote>“Building production-grade APIs in Rust has never been more accessible.” — Marcus Chen\u003C\u002Fblockquote>\u003Cp>That quote lands because the stack really does remove a lot of friction. SQLx catches schema problems at compile time, Actix handles typed extraction cleanly, and Postgres gives you the durability and concurrency model most serious APIs need. The catch is that each layer has sharp edges if you treat it like a toy project.\u003C\u002Fp>\u003Cp>Migrations are another example. SQLx’s timestamped migration files are easy to commit and review, but the offline query cache can break builds if you forget to prepare it. If your CI pipeline does not have access to a live database, you need the \u003Ccode>.sqlx\u003C\u002Fcode> directory checked in and refreshed before the build step.\u003C\u002Fp>\u003Ch2>Numbers that matter in practice\u003C\u002Fh2>\u003Cp>There are a few comparisons worth keeping in mind if you are choosing a Rust API stack today. The tutorial cites Actix Web as handling roughly 10 to 15 percent more requests per second than Axum under heavy load. That is real, but it is rarely the deciding factor for a CRUD service or internal API.\u003C\u002Fp>\u003Cp>The more meaningful numbers are operational. A well-built Rust container image often lands in the 20 to 50 MB range when you use a multistage Docker build. That is much smaller than the typical JVM image and usually smaller than a Python service with a full dependency tree. Smaller images mean faster deploys, less registry churn, and fewer surprises when you roll back.\u003C\u002Fp>\u003Cp>On the database side, the comparison between SQLx and Diesel is about query shape and async ergonomics. Diesel’s type system is impressive, but dynamic queries get painful fast. SQLx trades some of that compile-time abstraction for direct SQL and async-native behavior, which is easier to live with once your API has optional filters, joins, and evolving endpoints.\u003C\u002Fp>\u003Cul>\u003Cli>Actix Web vs Axum: roughly 10 to 15 percent higher throughput for Actix under heavy load, according to the tutorial’s cited benchmarks.\u003C\u002Fli>\u003Cli>Docker runtime images: often 20 to 50 MB for a Rust API built with a multistage Dockerfile.\u003C\u002Fli>\u003Cli>SQLx vs Diesel: SQLx keeps raw SQL and async-first behavior; Diesel favors compile-time query construction.\u003C\u002Fli>\u003Cli>PostgreSQL vs SQLite: Postgres handles pooled async workers and concurrent writes more cleanly for production APIs.\u003C\u002Fli>\u003C\u002Ful>\u003Cp>Testing is where the stack starts to feel serious. Integration tests against a Dockerized Postgres instance, plus \u003Ccode>sqlx::test\u003C\u002Fcode> macros, catch issues that unit tests miss. In CI, a GitHub Actions workflow with a Postgres service container is usually enough to keep the build honest without extra infrastructure.\u003C\u002Fp>\u003Ch2>What I would do if I were starting today\u003C\u002Fh2>\u003Cp>If I were building a new Rust API this week, I would take this stack almost exactly as written. I would use Actix Web for the HTTP layer, SQLx for database access, and PostgreSQL from the first commit. I would also make a few decisions early: commit migrations, run \u003Ccode>cargo sqlx prepare\u003C\u002Fcode> in CI, and map database errors to a central \u003Ccode>ResponseError\u003C\u002Fcode> enum instead of scattering ad hoc status codes through handlers.\u003C\u002Fp>\u003Cp>The biggest mistake is treating the stack like a tutorial toy. The second biggest is assuming async code means the hard parts disappear. They do not. They just move into places like connection pooling, migration discipline, and runtime compatibility.\u003C\u002Fp>\u003Cp>For teams that want Rust’s safety guarantees to extend beyond memory management and into request handling, SQL validation, and deployment shape, this is a practical stack with a clear operating model. My prediction is simple: the next wave of Rust backend adoption will come from teams that standardize on Actix, SQLx, and Postgres because it is easier to reason about than a pile of abstractions. If you are choosing a backend stack now, the better question is whether you want your compiler to catch schema mistakes before lunch or your pager to catch them at midnight.\u003C\u002Fp>\u003Cp>Related reading: \u003Ca href=\"\u002Fnews\u002Frust-analyzer-changelog-321\" target=\"_blank\" rel=\"noopener\">rust-analyzer changelog 321\u003C\u002Fa> for editor-side Rust workflow updates, and \u003Ca href=\"\u002Fnews\u002Foxirs-v0-2-4-semantic-web-rust\" target=\"_blank\" rel=\"noopener\">OxiRS v0.2.4\u003C\u002Fa> for another example of Rust moving deeper into production infrastructure.\u003C\u002Fp>","Actix Web, SQLx, and PostgreSQL give Rust teams a fast path to production APIs, with compile-time query checks and lean Docker images.","www.prismnews.com","https:\u002F\u002Fwww.prismnews.com\u002Fhobbies\u002Frust-programming\u002Fbuild-a-rest-api-with-actix-web-sqlx-and-postgresql-in-rust",null,"https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1775153217317-vih7.png",[13,14,15,16,17],"Rust APIs","Actix Web","SQLx","PostgreSQL","async Rust","en",2,false,"2026-04-02T18:06:40.188296+00:00","2026-04-02T18:06:40.076+00:00","done","81c4380a-b0fe-4df3-9887-051e53688c97","build-rust-rest-api-actix-sqlx-postgres-en","tools","497d44c4-928e-4682-a8bf-be8fe8a27934","published","2026-04-08T09:00:49.926+00:00",[31,33,35,37,39],{"name":17,"slug":32},"async-rust",{"name":15,"slug":34},"sqlx",{"name":14,"slug":36},"actix-web",{"name":13,"slug":38},"rust-apis",{"name":16,"slug":40},"postgresql",{"id":27,"slug":42,"title":43,"language":44},"build-rust-rest-api-actix-sqlx-postgres-zh","用 Actix、SQLx、Postgres 做 Rust …","zh",[46,52,58,64,70,76],{"id":47,"slug":48,"title":49,"cover_image":50,"image_url":50,"created_at":51,"category":26},"a6c1d84d-0d9c-4a5a-9ca0-960fbfc1412e","why-gemini-api-pricing-is-cheaper-than-it-looks-en","Why Gemini API pricing is cheaper than it looks","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1778869846824-s2r1.png","2026-05-15T18:30:26.595941+00:00",{"id":53,"slug":54,"title":55,"cover_image":56,"image_url":56,"created_at":57,"category":26},"8b02abfa-eb16-4853-8b15-63d302c7b587","why-vidhub-huiyuan-hutong-bushi-quan-shebei-tongyong-en","Why VidHub 会员互通不是“买一次全设备通用”","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1778789439875-uceq.png","2026-05-14T20:10:26.046635+00:00",{"id":59,"slug":60,"title":61,"cover_image":62,"image_url":62,"created_at":63,"category":26},"abe54a57-7461-4659-b2a0-99918dfd2a33","why-buns-zig-to-rust-experiment-is-right-en","Why Bun’s Zig-to-Rust experiment is the right move","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1778767895201-5745.png","2026-05-14T14:10:29.298057+00:00",{"id":65,"slug":66,"title":67,"cover_image":68,"image_url":68,"created_at":69,"category":26},"f0015918-251b-43d7-95af-032d2139f3f6","why-openai-api-pricing-is-product-strategy-en","Why OpenAI API pricing is a product strategy, not a footnote","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1778749841805-uyhg.png","2026-05-14T09:10:27.921211+00:00",{"id":71,"slug":72,"title":73,"cover_image":74,"image_url":74,"created_at":75,"category":26},"7096dab0-6d27-42d9-b951-7545a5dddf33","why-claude-code-prompt-design-beats-ide-copilots-en","Why Claude Code’s prompt design beats IDE copilots","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1778742651754-3kxk.png","2026-05-14T07:10:30.953808+00:00",{"id":77,"slug":78,"title":79,"cover_image":80,"image_url":80,"created_at":81,"category":26},"1f1bff1e-0ebc-4fa7-a078-64dc4b552548","why-databricks-model-serving-is-right-default-en","Why Databricks Model Serving is the right default for production infe…","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1778692290314-gopj.png","2026-05-13T17:10:32.167576+00:00",[83,88,93,98,103,108,113,118,123,128],{"id":84,"slug":85,"title":86,"created_at":87},"8008f1a9-7a00-4bad-88c9-3eedc9c6b4b1","surepath-ai-mcp-policy-controls-en","SurePath AI's New MCP Policy Controls Enhance AI Security","2026-03-26T01:26:52.222015+00:00",{"id":89,"slug":90,"title":91,"created_at":92},"27e39a8f-b65d-4f7b-a875-859e2b210156","mcp-standard-ai-tools-2026-en","MCP Standard in 2026: Integrating AI Tools","2026-03-26T01:27:43.127519+00:00",{"id":94,"slug":95,"title":96,"created_at":97},"165f9a19-c92d-46ba-b3f0-7125f662921d","rag-2026-transforming-enterprise-ai-en","How RAG in 2026 is Transforming Enterprise AI","2026-03-26T01:28:11.485236+00:00",{"id":99,"slug":100,"title":101,"created_at":102},"6a2a8e6e-b956-49d8-be12-cc47bdc132b2","mastering-ai-prompts-2026-guide-en","Mastering AI Prompts: A 2026 Guide for Developers","2026-03-26T01:29:07.835148+00:00",{"id":104,"slug":105,"title":106,"created_at":107},"d6653030-ee6d-4043-898d-d2de0388545b","evolving-world-prompt-engineering-en","The Evolving World of Prompt Engineering","2026-03-26T01:29:42.061205+00:00",{"id":109,"slug":110,"title":111,"created_at":112},"3ab2c67e-4664-4c67-a013-687a2f605814","garry-tan-open-sources-claude-code-toolkit-en","Garry Tan Open-Sources a Claude Code Toolkit","2026-03-26T08:26:20.245934+00:00",{"id":114,"slug":115,"title":116,"created_at":117},"66a7cbf8-7e76-41d4-9bbf-eaca9761bf69","github-ai-projects-to-watch-in-2026-en","20 GitHub AI Projects to Watch in 2026","2026-03-26T08:28:09.752027+00:00",{"id":119,"slug":120,"title":121,"created_at":122},"231306b3-1594-45b2-af81-bb80e41182f2","claude-code-vs-cursor-2026-en","Claude Code vs Cursor in 2026","2026-03-26T13:27:14.177468+00:00",{"id":124,"slug":125,"title":126,"created_at":127},"9f332fda-eace-448a-a292-2283951eee71","practical-github-guide-learning-ml-2026-en","A Practical GitHub Guide to Learning ML in 2026","2026-03-27T01:16:50.125678+00:00",{"id":129,"slug":130,"title":131,"created_at":132},"1b1f637d-0f4d-42bd-974b-07b53829144d","aiml-2026-student-ai-ml-lab-repo-review-en","AIML-2026 Is a Bare-Bones Student Lab Repo","2026-03-27T01:21:51.661231+00:00"]