Using Elastic Search with Rust actix-web
I am writing this post to document how to use Elastic Search with Rust actix-web.
The problem
As both actix-web uses tokio runtime internally to create async runtime and elastic search crate also uses tokio, we tried believed using actix-web
with elastic-search would be easy — however, hit the following error :
there is no reactor running, must be called from the context of Tokio runtime
The message says no tokio runtime running.
if we use #[tokio::main]
annotation with every handler. we get an error that we cannot start a runtime inside another runtime something like below:
Cannot start a runtime from within a runtime. This happens because a function (like `block_on`) attempted to block the current thread while the thread is being used to drive asynchronous tasks.
This is as there is an actix-web runtime already running and we are trying to start another inside it.
The solution
Deep dive research and we found out that the problem being both(actix-web and elasticsearch) were using different versions of tokio
So inorder to make these both crates work together the cargo.toml
file’s dependencies should be modified to handle versions as below:
[dependencies]
actix-web = "^3"
elasticsearch = "7.10.0-alpha.1"
or if you want to use latest version of elastic-search and are fine with beta version of actix-web
[dependencies]
actix-web = "4.0.0-beta.9"
elasticsearch = "7.14.0-alpha.1"
So let's use elastic search with actix-web
The working source code is available on our github repository here.
We will have to add serde_json crate, since elastic search is used with JAQL( json queries language)
[dependencies]
actix-web = "^3"
serde_json = "~1"
elasticsearch = "7.10.0-alpha.1"
Create a small actix-web app in main.rs
file. or you can take a look at main.rs file in source code. then create a file elastic.rs
in src/elastic.rs
. we are only going to work in this file. to include this file as module in main.rs
add this line at top or bottom:
//main.rs
mod elastic;
We will need a function to create a elastic client, add this function to elsatic.rs
Handler function for searching with elastic search
for this handler function, request body looks like below
{
"key": "user",
"value": "abhinav"
}
we can do a more complex search where the request body looks like below
{
"include": {
"key": "category",
"value": "women's"
},
"exclude": {
"key": "category",
"value": "men's"
}
}
by replacing the query variable in the above handler function with
Handler function for inserting index in elastic search
for this handler function, request body looks like below
{
"user": "abhinav"
}
Handler function to update index
for this handler function request body looks like below
{
"id": "user_id",
"change": "user name to update"
}
for more update scripts visit here.
Handle function for deleting index
for this handler function request body looks like below
{
"id": "user_id"
}
You can see the source code at GitHub.
Hope this helps and thank you for reading !!!