The Simplest Hello World in Node.js

Full source code available here.

I am learning Node.js and have found it a bit of a struggle to locate good, simple documentation. It feels like most people writing in the space assume a lot of existing knowledge, like you know how plenty of JavaScript, or how to effectively use web browser debug tools, have a good understanding of HTML and CSS. If you go down the rabbit hole of asynchronous programming in Node.js the writers often assume you know about the previous Node.js approach of asynchronous, try reading about async/await and you’ll be pointed to examples with promises, promisify, microtasks and callbacks, again assuming a lot of knowledge on the part of the reader.

I even asked a friend who was using Node.js to build a complex web site to write a simple Hello World program for me that I could run from the command line, but he didn’t know. This was a very experienced developer working in the industry for almost thirty years, but he started with Node.js inside a an existing web site.

If you search for how to write a “Hello world” in Node.js, you’ll find examples that setup web servers, take requests, return response, and probably use callbacks.

Because of what I perceive as a lack of documentation, I’m going write some simple blog posts about things I learn but could not find a simple example of.

To kick off, here is Hello World in Node.js.

I’m going assume you have Node and the Node Package Manager installed, and that you can run node and npm from the command line. If you do not have them installed there is plenty of help out there for that!

Hello World
Create a new directory called SimpleHelloWorld.

Open a terminal/console inside that directory.

Run –

npm init -y

This creates a package.json file, you will edit this in a moment.

Create a new file called helloworld.js.

Add a single line to the file –

console.log("Hello World");

At this point you can run –

node helloworld.js

And you will see “Hello World” printed. There you a simple Hello World program.

Let’s do one more thing, open package.json.

Replace the scripts section with –

 "scripts": {
    "start": "node helloworld.js"
  },

Now you can run –

npm start

Full source code available here.

Entity Framework Core 3.1 Bug vs 2.2, Speed and Memory During Streaming

Full source code available here.

A while ago I wrote a blog post about the advantages of streaming results from Entity Framework Core as opposed to materializing them inside a controller and the returning the results. I saw very significant improvements in memory consumption when streaming as shown in the chart below.

For this post I updated the code to use Entity Framework Core 3.1.8 on .NET Core 3.1 and was very surprised to see that streaming data did not work as before. Memory usage was high and the speed of the response was much poorer than I expected.

I tried Entity Framework Core 2.2.6 on .NET Core 3.1, and it behaved as I expected, fast and low memory.

Below is how I carried out my comparison.

The Setup
A simple Web API application using .NET Core 3.1.

A local db seeded with 10,000 rows of data using AutoFixture.

An API controller with a single action method that returns data from the database. Tracking of Entity Framework entities is turned off.

[Route("api/[controller]")]
[ApiController]
public class ProductsController : ControllerBase
{
    private readonly SalesContext _salesContext;

    public ProductsController(SalesContext salesContext)
    {
        _salesContext = salesContext;
    }

    [HttpGet("streaming/{count}")]
    public ActionResult GetStreamingFromService(int count)
    {
        IQueryable<Product> products = _salesContext.Products.OrderBy(o => o.ProductId).Take(count).AsNoTracking();
        return Ok(products);
    }
}

It’s a very simple application.

The Test
I “warm up” the application by making a few requests.

Then I use Fiddler to hit the products endpoint 20 times, each request returns 8,000 products.

I do the same for both Entity Framework Core 3.1.8 and Entity Framework Core 2.2.6.

The Results
Framework Core 2.2.6 out performs Framework Core 3.1.8 in both speed of response and memory consumption.

Here is the comparison of how quickly they both load the full set of results.

Time to First Byte (TTFB) –

  • EF 2.2.6 returns data before we even reach 10ms in all cases and before 2ms in most cases.
  • EF 3.1.8 is never faster than 80ms and six requests take more than 100ms.

Overall Elapsed –

  • EF 2.2.6 returns most requests in the 26ms to 39ms range, with only two taking more than 40ms.
  • EF 3.1.8 returns four requests in less than 100ms. The rest are in the 100ms to 115ms range.

The speed difference between EF Core 2.2.6 and EF Core 3.1.8 is significant, to say the least.

Memory Usage –

Here is the graph of memory usage during the test.

  • EF Core 2.2.6 maintains low memory usage.
  • EF Core 3.1.8 consumes significantly more memory to do the same job.

Remember, they are both using the same application code, it’s only the versions of Entity Framework that differ.

I also performed tests with other versions of Entity Framework Core 3.1.*, and Entity Framework 2.* and same very similar results. It seems something in the 3.1 stack is done very differently than the 2.* stack.

As always, you can try it for yourself with the attached zip.

Full source code available here.

Getting Started with ElasticSearch, Part 2 – Searching with a HttpClient

Full source code available here.

In the previous blog post I showed how to setup ElasticSearch, create and index and seed the index with some sample documents. That is not a lot of use without the ability to search it.

In this post I will show how to use a typed HttpClient to perform searches. I’ve chosen not to use the two libraries provided by the Elasticsearch company because I want to stick with JSON requests that I can write and test with any tool like Fiddler, Postman or Rest Client for Visual Studio Code.

If you haven’t worked with HttpClientFactory you can check out my postsElasticSearchHttpClientFactory on it or the Microsoft docs page.

The Typed HttpClient
A typed HttpClient lets you, in a sense, hide away that you are using a HttpClient at all. The methods the typed client exposes are more business related than technical – the the type of request, the body of the request, how the response is handled are all hidden away from the consumer. Using a typed client feels like using any other class with exposed methods.

This typed client will expose three methods, one to search by company name, one to search my customer name and state, and one to return all results in a paged manner.

Start with an interface that specifies the methods to expose –

public interface ISearchService
{
    Task<string> CompanyName(string companyName);
    Task<string> NameAndState(string name, string state);
    Task<string> All(int skip, int take, string orderBy, string direction);
}

Create the class that implements that interface and takes a HttpClient as a constructor parameter –

public class SearchService : ISearchService
{
    private readonly HttpClient _httpClient;
    public SearchService(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }
    //snip...

Implement the search functionality (and yes, I don’t like the amount of escaping I need to send a simple request with a JSON body) –

public async Task<string> CompanyName(string companyName)
{
    string query = @"{{
                        ""query"": {{
                            ""match_phrase_prefix"": {{ ""companyName"" : ""{0}"" }} 
                        }}
                    }}";
    string queryWithParams = string.Format(query, companyName);
    return await SendRequest(queryWithParams);
}

public async Task<string> NameAndState(string name, string state)
{
    string query = @"{{
                        ""query"": {{
                            ""bool"": {{
                                ""must"": [
                                    {{""match_phrase_prefix"": {{ ""fullName"" : ""{0}"" }} }}
                                    ,{{""match"": {{ ""address.state"" : ""{1}""}}}} 
                                ]
                            }}
                        }}
                    }}";
    string queryWithParams = string.Format(query, name, state);
    return await SendRequest(queryWithParams);
}

public async Task<string> All(int skip, int take, string orderBy, string direction)
{
    string query = @"{{
                    ""sort"":{{""{2}"": {{""order"":""{3}""}}}},
                    ""from"": {0},
                    ""size"": {1}
                    }}";

    string queryWithParams = string.Format(query, skip, take, orderBy, direction);
    return await SendRequest(queryWithParams);
}

And finally send the requests to the ElasticSearch server –

private async Task<string> SendRequest(string queryWithParams)
{
    var request = new HttpRequestMessage()
    {
        Method = HttpMethod.Get,
        Content = new StringContent(queryWithParams, Encoding.UTF8, "application/json")
    };
    var response = await _httpClient.SendAsync(request);
    var content = await response.Content.ReadAsStringAsync();
    return content;
}

The Setup
That’s the typed client taken care of, but it has be added to the HttpClientFactory, that is done in Startup.cs.

In the ConfigureServices(..) method add this –

services.AddHttpClient<ISearchService, SearchService>(client =>
{
    client.BaseAddress = new Uri("http://localhost:9200/customers/_search");
});

I am running ElasticSearch on localhost:9200.

That’s all there is to registering the HttpClient with the factory. Now all that is left is to use the typed client in the controller.

Searching
The typed client is passed to the controller via constructor injection –

[ApiController]
[Route("[controller]")]
public class SearchController : ControllerBase
{
    private readonly ISearchService _searchService;
    public SearchController(ISearchService searchService)
    {
        _searchService = searchService;
    }
    //snip...

Add some action methods to respond to API requests and call the methods on the typed client.

[HttpGet("company/{companyName}")]
public async Task<ActionResult> GetCompany(string companyName)
{
    var result = await _searchService.CompanyName(companyName);
    return Ok(result);
}

[HttpGet("nameAndState/")]
public async Task<ActionResult> GetNameAndState(string name, string state)
{
    var result = await _searchService.NameAndState(name, state);
    return Ok(result);
}

[HttpGet("all/")]
public async Task<ActionResult> GetAll(int skip = 0, int take = 10, string orderBy = "dateOfBirth", string direction = "asc")
{
    var result = await _searchService.All(skip, take, orderBy, direction);
    return Ok(result);
}

That’s it. You are up and running with ElasticSearch, a seeded index, and an API to perform searches.

In the next post I’ll show you how to deploy ElasticSearch to AWS with some nice infrastructure as code.

Full source code available here.