In fact, Rust is not suitable for developing Web API

Rust is an amazing programming language with very good CLI tools, such as ripgrep and exa. Companies like Cloudflare are using and encouraging people to write Rust to run microservices. Software written in Rust may be safer, smaller, and cleaner than C++ or C.

If I am writing a geocoder, a routing engine, a real-time messaging platform, a database, or a CLI tool, Rust is most suitable.

But last year, I tried to use Rust to write a pure API service for a traditional website, and Rust was not suitable.

1 Missing many small features

Rust has a large number of web service frameworks, database connectors, and parsers. But there are only very low-level components for building an authentication service. Node.js has passport.js, Rails has design, and Django has an out-of-the-box authentication model. In Rust, you need to learn how to convert shared Vec to the underlying encryption library to build this system (Translator’s Note, Vec is A dynamic array will only grow automatically but not shrink. Unlike Array, Vec has the ability to dynamically add and delete elements, and it can be accessed randomly with O(1) efficiency. All content items in Vec are generated In the heap space, Vec can be easily moved out of a stack without worrying about memory copy affecting execution efficiency, after all, just copy the pointer on the stack). Some libraries try to solve this problem, such as libreauth, but it has only just started development. There are many similar web framework issues.

What about the SDK? In mainstream programming languages, you can access Google Cloud Services, AWS or Stripe through an official library. Most of these official libraries are great. For example, the aws-sdk-js and Stripe libraries are very well designed and maintained.

Rust is not like that. There are only a few third-party libraries, but with the development speed of these services, can they really provide a high-quality experience?

Someone will say okay, the X programming language is so good, you can write an SDK yourself on the weekend! I must answer, no.

Rust's ecosystem is very rich in other areas. The crates used to build the CLI, manage concurrency, use binary data, and the underlying parser are impressive and great.

2Rust compiler is faster than before, but still very slow

I have been watching Nicholas Nethercote's blog, describing how the Rust team optimized the compiler to make it faster!

But compared with other programming languages, building websites with it will be very slow. It is much slower than the compiled programming language Go, and also much slower than the interpreted programming languages ​​JavaScript, Ruby and Python.

Once the code is compiled, everything becomes great! But in my case, even the basic API functions were incomplete, an uncomplicated system-it took more than 10 minutes to compile. The hardware configuration built by Google code is very poor, it will time out every time, and I can't compile anything.

As long as the cache dependencies are not rebuilt, the cache makes sense. Maybe reducing dependencies will speed up Rust project compilation. But like serde, JSON and other serialization/deserialization programs used by almost everyone take up a lot of compilation time. Should we replace serde with something that compiles faster but lacks extensive documentation and ecosystem support? This trade-off is very bad.

3Rust is complicated

Rust allows you to think from the code dimension, which is very important for system programming. It makes you think about how to share or copy memory, think about real but unlikely events with small probability, and make sure to handle them properly, and help you write a variety of efficient codes.

These concerns are reasonable, but for most web applications, they are not the most important concerns. Thinking with popular inertia can lead to incorrect assumptions.

Take Rust's security as an example. This is an important part of its slogan, which is absolutely correct: Rust's promise of security and the bottom layer are both-it can work without a garbage collector while preventing memory-based vulnerabilities. When you read about "safety", think of Rust's competitor C. Code in C language can refer to any memory, which is prone to overflow and error. Rust code can be as fast as C code, but can protect memory access without the need for a garbage collector or some kind of runtime checking.

But Rust's memory rules are not more secure than Node.js or Python, and Web applications written in Rust will not be safer than Python or Ruby applications on the system. High-level programming languages ​​with garbage collectors usually pay performance losses to avoid such exploits and errors. You cannot refer to uninitialized memory in JavaScript, because there is no inter-memory reference in JavaScript.

Side note: This is describing the design goals of Node.js and other systems-they do have bugs occasionally. Node.js cache objects are worth reading.

If you ask some people, they will say that if you use unsafe code, Rust is unsafe compared to programming languages ​​with memory reclamation-including the most popular web framework Actix (Translator's Note, Actix is ​​Rust's Actor asynchronous Concurrency framework, based on Tokio and Future, has asynchronous non-blocking event-driven concurrency out of the box. It implements a low-level Actor model to provide a lock-free concurrency model, and at the same time provides a synchronous Actor, which is fast, reliable, and easily scalable https:// actix.rs/), because unsafe code allows the delay of raw pointers.

If you are writing a video game, it is not good to pause garbage collection. If you are writing microcontroller code, any memory "overhead" or waste is very bad. But most web applications can save a little memory overhead in exchange for production performance.

Other attributes of Rust face almost the same controversy. Its concurrency is amazing. If you are doing something complicated and need to respond quickly, this is certainly great. But what if this is not the case? To say the least, Rust's asynchronous ecosystem is facing great challenges: there are different asynchronous implementations in various unrelated fields, such as tokio.

In comparison, Python's Tornado and Twisted are implemented asynchronously, and Node.js implements it asynchronously, but the syntax is very ugly.

I am sure that Rust's asynchrony will be stable and unified, and will be easier to operate in the future, but I will use it now.

4The Rust ecosystem is not Web-centric

Many people are learning Rust, using Rust to write CLI applications or low-level code, and have a great time. There are significantly fewer people using Rust to write ordinary web applications.

This is an important part of the technology choice: Is anyone using the tool? Are they roughly in the same field? Unfortunately, many of the incredibly exciting work in the Rust ecosystem has nothing to do with web application servers. There are indeed some promising web frameworks-even higher-level frameworks, but there is no doubt that their market is small. Even the main web framework Actix has only a few top contributors.

If Rust grows at the current rate, then the Web part of the community will reach a critical value, but I don't think that enough people use Rust as a practical tool for websites. Compared with other communities, many companies are committed to using existing tools to build Web applications. These tools are not the most cutting-edge, but sufficient to distinguish mature technologies from new technologies.

5Juniper's N+1 queries

This part is not only Rust, it also involves the GraphQL ecosystem, and Rust's participation in this ecosystem is an example.

The N+1 problem is something everyone who builds a web application should know. The main point is: you have a page of photos (one query) and you want to display the author of each photo. How many queries will there be: 1. Combine the photo and the author, or query each photo to get the author after retrieving the photo? Or twice, query user.id in ids for the second time, get all authors once, and then reset their photo attributes.

N+1 queries are usually solved by using the database first: for example, changing the N+1 query to a single query will bring obvious performance optimization. We have many ways to try and solve these problems: you can write SQL, and try to use CTE and JOIN to complete a lot of work in a single query, as we do in Observable, or use an ORM layer like ActiveRecord to A quick way to convert N+1 queries into predictable queries.

Juniper is a GraphQL service for Rust applications. GraphQL basically defines the query by the front-end application, not the back-end. Give it a series of things that can be queried, and then the application (React or other) sends any query to the backend.

This complicates the back end. Any SQL-level optimization is impossible-your server is writing dynamic SQL, optimization can only rely on GraphQL services, but it will not always be effective. For example: Juniper executes N+1 queries by default, and the solution dataloader is relatively crude and needs to be maintained separately. Therefore, in the end you will have a very fast application layer, but all of its time is spent on extremely inefficient database queries.

In short, GraphQL works very well with NoSQL databases, and it can quickly provide services for these types of requests. I'm sure that Facebook has some specific databases and GraphQL works very well, but other companies in the industry rely heavily on Postgres and similar products.

6 some notes

First of all, the issues mentioned in this article are not aimed at using Rust in general scenarios, but only at using Rust for specific goals and ecosystems, which is simply Web API.

Note 1: Generally, you can build a website in any programming language. Remember OkCupid based on C++? (Translator's Note, OkCupid is a large online dating site in the United States) There is also a very popular astrology application, Co-star, which is all written in Haskell. If you are good at other programming languages, or you can recruit engineers who are good at these programming languages, you can also be successful.

Note 2: What I am trying to build is a web application API that re-CRUD (addition, deletion, modification, and checking). It may not be regarded as a Web "service"-mainly to perform the same operation quickly and countless times, but a Web "application"-which performs many different operations and contains a considerable amount of business logic. If what you are developing is different from what I am doing, then my advice may not be suitable for you. If what you need is to perform one or two operations quickly, for example, you are writing a payment gateway or voice messaging application, then Rust may work well.

Note 3: This article was written in January 2021. If the community continues to develop in the future, Rust will be continuously improved, and it will become better and easier to develop web applications.

All in all, I really like to use Rust, which is a beautiful programming language with a lot of cool ideas. Hope that soon, Rust will become the most suitable tool to build what I want to do. However, many things I want to do now have to use programming languages ​​with different characteristics to run better.

Original English link: https://macwright.com/2021/01/15/rust.html

1. The domestically-made alternatives are intangible? Come back to the Zhaoyi Innovation Live Class!

2. Can the open source RISC-V be the antidote to China's "core shortage"?

3. Raspberry Pi Pico: MCU for only $4

4. There are many reasons why MCU supports AI function~

5. In 2020, 20 software engineering principles I learned~

6. The application of state machine ideas in embedded development~

Disclaimer: This article is reproduced online, and the copyright belongs to the original author. If you are involved in copyright issues, please contact us, we will confirm the copyright based on the copyright certification materials you provide and pay the author's remuneration or delete the content.

Guess you like

Origin blog.csdn.net/DP29syM41zyGndVF/article/details/113577279