<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: John Ojo</title>
    <description>The latest articles on DEV Community by John Ojo (@jioophoenix).</description>
    <link>https://dev.to/jioophoenix</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F486121%2Fa81c0ca5-08da-4f51-b5f8-1d469dc199c5.png</url>
      <title>DEV Community: John Ojo</title>
      <link>https://dev.to/jioophoenix</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jioophoenix"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>John Ojo</dc:creator>
      <pubDate>Wed, 10 Sep 2025 04:07:33 +0000</pubDate>
      <link>https://dev.to/jioophoenix/-2fi</link>
      <guid>https://dev.to/jioophoenix/-2fi</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/jioophoenix/understanding-linear-regression-inside-out-practical-implementation-with-scikit-learn-and-110k" class="crayons-story__hidden-navigation-link"&gt;Understanding Linear Regression Inside-Out: Practical Implementation with scikit-learn and TensorFlow&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/jioophoenix" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F486121%2Fa81c0ca5-08da-4f51-b5f8-1d469dc199c5.png" alt="jioophoenix profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/jioophoenix" class="crayons-story__secondary fw-medium m:hidden"&gt;
              John Ojo
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                John Ojo
                
              
              &lt;div id="story-author-preview-content-2726296" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/jioophoenix" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F486121%2Fa81c0ca5-08da-4f51-b5f8-1d469dc199c5.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;John Ojo&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/jioophoenix/understanding-linear-regression-inside-out-practical-implementation-with-scikit-learn-and-110k" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Aug 2 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/jioophoenix/understanding-linear-regression-inside-out-practical-implementation-with-scikit-learn-and-110k" id="article-link-2726296"&gt;
          Understanding Linear Regression Inside-Out: Practical Implementation with scikit-learn and TensorFlow
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/machinelearning"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;machinelearning&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/python"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;python&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/linearregression"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;linearregression&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/jioophoenix/understanding-linear-regression-inside-out-practical-implementation-with-scikit-learn-and-110k" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt; reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/jioophoenix/understanding-linear-regression-inside-out-practical-implementation-with-scikit-learn-and-110k#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            4 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>ai</category>
      <category>linearregression</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>John Ojo</dc:creator>
      <pubDate>Sat, 06 Sep 2025 16:21:44 +0000</pubDate>
      <link>https://dev.to/jioophoenix/-4mj7</link>
      <guid>https://dev.to/jioophoenix/-4mj7</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/jioophoenix" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F486121%2Fa81c0ca5-08da-4f51-b5f8-1d469dc199c5.png" alt="jioophoenix"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/jioophoenix/understanding-linear-regression-inside-out-gradients-loss-and-learning-from-scratch-1ld8" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Understanding Linear Regression Inside-Out: Gradients, Loss, and Learning from Scratch&lt;/h2&gt;
      &lt;h3&gt;John Ojo ・ Jul 19&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#machinelearning&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#linearregression&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#python&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#ai&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>machinelearning</category>
      <category>linearregression</category>
      <category>python</category>
      <category>ai</category>
    </item>
    <item>
      <title>Understanding Linear Regression Inside-Out: Practical Implementation with scikit-learn and TensorFlow</title>
      <dc:creator>John Ojo</dc:creator>
      <pubDate>Sat, 02 Aug 2025 15:38:14 +0000</pubDate>
      <link>https://dev.to/jioophoenix/understanding-linear-regression-inside-out-practical-implementation-with-scikit-learn-and-110k</link>
      <guid>https://dev.to/jioophoenix/understanding-linear-regression-inside-out-practical-implementation-with-scikit-learn-and-110k</guid>
      <description>&lt;p&gt;Welcome back to Part 2 of the series:&lt;br&gt;
“Understanding Linear Regression Inside-Out"&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://dev.to/jioophoenix/understanding-linear-regression-inside-out-gradients-loss-and-learning-from-scratch-1ld8"&gt;Part 1&lt;/a&gt;, we explored the foundations of linear regression by building it from scratch using NumPy. We delved into concepts like prediction, loss gradient, and gradient descent, gaining an inside-out understanding of how linear regression models learn.&lt;/p&gt;

&lt;p&gt;While implementing these algorithms manually is essential for learning, real-world machine learning applications require more efficient, scalable, and production-ready tools. In this second part, we shift our focus to practical implementations employing two widely used machine learning libraries: scikit-learn and TensorFlow.&lt;/p&gt;

&lt;p&gt;We'll use the same dataset with identical data loading logic, so we'll skip that section (refer to &lt;a href="https://dev.to/jioophoenix/understanding-linear-regression-inside-out-gradients-loss-and-learning-from-scratch-1ld8"&gt;Part 1's Data Processing&lt;/a&gt; section if needed). Although scikit-learn doesn't require normalization, we'll maintain the same preprocessing steps.&lt;/p&gt;

&lt;p&gt;Let’s dive in.&lt;/p&gt;

&lt;p&gt;The source code on GitHub : &lt;a href="https://github.com/JIOO-phoeNIX/artificial-intelligence-projects/blob/main/linear_regression_with_library.ipynb" rel="noopener noreferrer"&gt;Linear Regression Using Library&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://jupyter.org/install" rel="noopener noreferrer"&gt;jupyter notebook setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;A local Python env setup with packages: numpy, matplotlib, sklearn, and tensorflow&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  scikit-learn Implementation
&lt;/h2&gt;

&lt;p&gt;scikit-learn's LinearRegression model is straightforward to use. You instantiate it, fit it to your training data, and then call predict() on your test data. During the fitting process, the model learns the best parameters (weights and bias), the same goal we achieved with gradient descent in Part 1.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Train Linear Regression model using sklearn
# Initialize and train the Linear Regression model
sklearn_model = LinearRegression()
sklearn_model.fit(X_train_norm, y_train)

# Make predictions on validation and test sets
val_predictions = sklearn_model.predict(X_val_norm)
y_predict_sklearn = sklearn_model.predict(X_test_norm)

# Calculate mean squared error for both validation and test sets
val_loss = mean_squared_error(y_val, val_predictions)
test_loss = mean_squared_error(y_test, y_predict_sklearn)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all you need to train a Linear Regression model using scikit-learn. From there, you can evaluate performance like mean squared error and plot actual vs predicted value comparisons.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;print(f"Validation MSE: {val_loss:.4f}")
print(f"Test MSE: {test_loss:.4f}")

# Create a plot comparing actual vs predicted sales
utils.plot_predictions(y_test, y_predict_sklearn, 'Predicted vs Actual Sales', 'Actual Sales', 'Predicted Sales')

# Print the first 25 actual and predicted values for comparison
for i in range(25):
    print("Print actual vs predicted values")
    print(f"Actual: {y_test[i]}, Predicted: {y_predict_sklearn[i]:.1f}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnb1e8pq0lexjuuos7c25.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnb1e8pq0lexjuuos7c25.png" alt="Sklearn Preduction vs Actual plot" width="648" height="620"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you compare this plot to the one from Part 1, you'll see we get the same results&lt;/p&gt;

&lt;h2&gt;
  
  
  Tensorflow Implementation
&lt;/h2&gt;

&lt;p&gt;TensorFlow takes a neural network approach. We'll create a simple one-layer neural network, use summary() to view the model architecture, and then model.fit() will learn the best parameters (weights and bias), just like our gradient descent implementation in Part 1, and then call predict() on your test data to make new predictions&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Train Linear Regression model using TensorFlow
# Define a simple Sequential model with a Dense layer (1 unit for linear regression)
tf_model = tf.keras.Sequential([
    tf.keras.layers.Input(shape=(X_train_norm.shape[1],)),
    tf.keras.layers.Dense(1)  # Linear regression (no activation)
])

# Display model architecture
tf_model.summary()

# Configure the model training parameters
tf_model.compile(
    optimizer=tf.keras.optimizers.SGD(learning_rate=0.01),
    loss='mse', # Mean Squared Error loss
    metrics=['mae'] # Track Mean Absolute Error during training
)

# Train the model
history = tf_model.fit(
    X_train_norm, y_train,
    validation_data=(X_val_norm, y_val),
    epochs=200,
    batch_size=32
)

# Evaluate on test data
test_loss, test_mae = tf_model.evaluate(X_test_norm, y_test, verbose=0)

# Generate predictions on test data
y_predict_tf = tf_model.predict(X_test_norm).flatten() # Flatten converts 2D array to 1D for easier comparison
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all you need to train a Linear Regression model using Tensorflow. You can also evaluate performance like mean squared error and plot actual vs predicted value comparisons.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;print(f"Test Loss (MSE): {test_loss:.4f}")
print(f"Test Mean Absolute Error: {test_mae:.4f}")

# Create a plot comparing actual vs predicted sales
utils.plot_predictions(y_test, y_predict_tf, 'Predicted vs Actual Sales', 'Actual Sales', 'Predicted Sales')

# Print the first 25 actual and predicted values for comparison
for i in range(25):
    print("Print actual vs predicted values")
    print(f"Actual: {y_test[i]}, Predicted: {y_predict_tf[i]:.1f}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvwc8truh9jj4pyaklphp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvwc8truh9jj4pyaklphp.png" alt="TF Preduction vs Actual plot" width="690" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Comparing this output to our results from Part 1 and those from scikit-learn, you'll see they are virtually identical.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this second part of the series, we transitioned from building linear regression from scratch to using powerful machine learning libraries, scikit-learn and TensorFlow, to implement the same model more efficiently. &lt;/p&gt;

&lt;p&gt;What’s particularly rewarding is how both approaches — manual and library-based — converged to similar results. This reinforces the foundational concepts covered in Part 1, while also demonstrating the real-world value of leveraging mature frameworks for faster development and scalability.&lt;/p&gt;

&lt;p&gt;Understanding what's happening under the hood, while also knowing how to use the tools available, gives you a balanced and confident footing in your machine learning journey. &lt;/p&gt;

&lt;p&gt;Thanks for following along! If you found this helpful or have questions, feel free to reach out. &lt;a href="https://coff.ee/johnojo" rel="noopener noreferrer"&gt;You can also buy me a coffee&lt;/a&gt; — happy learning!&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>ai</category>
      <category>linearregression</category>
    </item>
    <item>
      <title>Understanding Linear Regression Inside-Out: Gradients, Loss, and Learning from Scratch</title>
      <dc:creator>John Ojo</dc:creator>
      <pubDate>Sat, 19 Jul 2025 13:17:25 +0000</pubDate>
      <link>https://dev.to/jioophoenix/understanding-linear-regression-inside-out-gradients-loss-and-learning-from-scratch-1ld8</link>
      <guid>https://dev.to/jioophoenix/understanding-linear-regression-inside-out-gradients-loss-and-learning-from-scratch-1ld8</guid>
      <description>&lt;p&gt;This article is beginner-friendly for those looking to break into Artificial Intelligence/Machine Learning, as well as for those with experience who want to understand what goes on behind the scenes of most ML algorithms.&lt;br&gt;
This will be a two-part series. In this part, I will explain the fundamentals of linear regression models and how they work behind the scenes to train and make predictions. In the next section, I will demonstrate how to utilize scikit-learn and TensorFlow to achieve this.&lt;br&gt;
Understanding the fundamentals is always valuable—when things aren’t working as expected, a solid foundation helps us troubleshoot more effectively.&lt;/p&gt;

&lt;p&gt;The source code on GitHub : &lt;a href="https://github.com/JIOO-phoeNIX/artificial-intelligence-projects/blob/main/basic_linear_regression.ipynb" rel="noopener noreferrer"&gt;Basic Linear Regression&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://jupyter.org/install" rel="noopener noreferrer"&gt;jupyter notebook setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;A local Python env setup with packages: numpy, matplotlib, sklearn, and tensorflow&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Supervised machine learning trains models using labeled data, where each example consists of both input features and the corresponding target variable. After training, the model can make predictions on new data points. &lt;/p&gt;

&lt;p&gt;Linear regression is one of the simplest yet most foundational algorithms in machine learning. It models the relationship between input features and a continuous target variable, forming the basis for more complex models used in modern predictive analytics. Linear regression is particularly useful for predicting continuous values like weather forecasts, sales figures, or stock prices. &lt;/p&gt;

&lt;p&gt;Libraries like scikit-learn and TensorFlow make training a linear regression model straightforward using just a few lines of code. However, this convenience can become a black box that obscures how the model learns, which is why, in this article, we’ll demystify linear regression by building it completely from scratch — using only NumPy for mathematical operations with just a touch of TensorFlow for data normalization.&lt;/p&gt;

&lt;p&gt;We’ll work with the classic advertising dataset, where the goal is to predict sales based on advertising spend across TV, radio, and newspapers. Along the way, we’ll cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Loading and preprocessing real-world data;&lt;/li&gt;
&lt;li&gt;Implementing the prediction function, loss calculation, and gradient descent manually;&lt;/li&gt;
&lt;li&gt;Evaluating the model on a separate test set; and&lt;/li&gt;
&lt;li&gt;Visualizing model performance with clear plots.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the end, you’ll not only understand what linear regression does, but also why it works and how to implement it step by step. Whether you're new to machine learning or looking to strengthen your foundations, this hands-on project will sharpen your skills.&lt;/p&gt;

&lt;p&gt;Stick with me—this will be a bit long, as we’re covering everything from loading and processing the data, to calculating loss, implementing gradient descent, making predictions, and doing it all manually.&lt;/p&gt;

&lt;p&gt;Let’s dive in.&lt;/p&gt;
&lt;h2&gt;
  
  
  Data Processing
&lt;/h2&gt;

&lt;p&gt;In this project, we’ll use the advertising dataset, a well-known dataset in the machine learning community. It’s often used for regression problems, particularly for demonstrating how different types of advertising affect product sales.&lt;/p&gt;

&lt;p&gt;The dataset contains 200 rows, and includes the following columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tv    Advertising budget spent on TV &lt;/li&gt;
&lt;li&gt;radio Advertising budget spent on radio&lt;/li&gt;
&lt;li&gt;newspaper Advertising budget spent on newspapers&lt;/li&gt;
&lt;li&gt;Sales Product sales&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s a quick look at the first few rows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;id   tv     radio  newspaper  sales
1   230.1   37.8    69.2      22.1
2    44.5   39.3    45.1      10.4
3    17.2   45.9    69.3       9.3
4   151.5   41.3    58.5      18.5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In our model:&lt;br&gt;
The input features (X) will be: tv, radio, and newspaper&lt;br&gt;
The target variable (y) will be: sales&lt;/p&gt;

&lt;p&gt;This setup is ideal for linear regression because we want to predict a continuous value (sales) based on numerical inputs.&lt;/p&gt;

&lt;p&gt;Before training, we’ll split the data into training, validation, and test sets, and normalize the features to ensure they are all on a similar scale. That way, our gradient descent optimizer can converge more efficiently.&lt;/p&gt;

&lt;p&gt;Let’s get started by loading the needed packages.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
import tensorflow as tf
import utils as utils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;NumPy: a popular library for scientific computing&lt;br&gt;
Matplotlib: a popular library for plotting data&lt;br&gt;
scikit-learn: just for splitting the dataset&lt;br&gt;
TensorFlow: only for normalizing the input features&lt;br&gt;
utils.py: contains helper functions needed to load the CSV data, extract the features and target from a dataset, and plot relevant graphs (loss, predictions).&lt;/p&gt;

&lt;p&gt;Next is loading and preprocessing the data&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;raw_data = utils.load_csv_data('&amp;lt;local-path&amp;gt;/data/Advertising.csv')

feature_keys = ['tv', 'radio', 'newspaper']
target_key = 'sales'

X, y = utils.prepare_data(raw_data, feature_keys, target_key)

print("X Shape: ", X.shape)
print("X length: ", len(X))
print("X first 5 features: ", X[:5])
print("X type: ", type(X))

print("y Shape: ", y.shape)
print("y length: ", len(y))
print("y first 5 features: ", y[:5])
print("y type: ", type(y))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Make sure to update the local-path. The utils.load_csv_data() function loads the dataset from the CSV file. After loading the raw data, we’ll convert the relevant columns into NumPy arrays for processing. utils.prepare_data() takes the raw data, the feature keys, and the target key, then returns a tuple of the features and target NumPy arrays. We print the shape, length, type, and the first 5 items in the features and target arrays. This enables us to get a sense of the data we are working with.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffnym5g3zl8wg3z67bnxo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffnym5g3zl8wg3z67bnxo.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, we can plot our features vs the target graph to visualize our data&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Plot the first 5 features vs target
print("Plot first 5 X vs y")
utils.plot_features_vs_target(X[:5], y[:5], feature_keys, target_key)

# Plot the entire features vs target
print("Plot entire X vs y")
utils.plot_features_vs_target(X, y, feature_keys, target_key)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Next, we process the data and get it ready for training.&lt;br&gt;
To simulate a realistic training workflow, we split the data into three parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;75% for training&lt;/li&gt;
&lt;li&gt;12.5% for validation (model tuning to ensure the model is not overfitting on the training data)&lt;/li&gt;
&lt;li&gt;12.5% for final testing (unseen data)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To help gradient descent converge efficiently, we normalize the features using TensorFlow’s Normalization layer, trained on the training set only to prevent data leakage.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Step 1: Split the dataset into training, validation, and test sets
# First split: 75% training, 25% temporary set
X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.25, random_state=55)
# Second split: Divide the temporary set into validation and test sets (50% each, which is 12.5% of the original data each)
X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.50, random_state=55)

# Step 2: Normalize using TensorFlow (adapt on train only)
# Create a normalization layer that will standardize the features
normalizer = tf.keras.layers.Normalization(axis=-1)
# Fit the normalizer only on training data to avoid data leakage
normalizer.adapt(X_train)  # Only fit on training data

# Step 3: Transform all datasets using the fitted normalizer
# Apply normalization to training data and convert to numpy array
X_train_norm = normalizer(X_train).numpy()
# Apply same normalization to validation data
X_val_norm = normalizer(X_val).numpy() 
# Apply same normalization to test data
X_test_norm = normalizer(X_test).numpy()

# Print shapes of all datasets to verify the splitting worked correctly
print("X_train_norm Shape: ", X_train_norm.shape)
print("y_train Shape: ", y_train.shape)
print("X_val_norm Shape: ", X_val_norm.shape)
print("y_val Shape: ", y_val.shape)
print("X_test_norm Shape: ", X_test_norm.shape)
print("y_test Shape: ", y_test.shape)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;At this point, our data is clean, split, and ready to be used for training a linear regression model from scratch. Next up, we’ll implement the linear regression components one by one: prediction, loss function, gradient calculation, weight and bias update using gradient descent, and training. Apologies in advance as I will not go deep into the mathematical equations used, but there are resources available online if you need to explore this further. Let’s get into it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Prediction Definition
&lt;/h2&gt;

&lt;p&gt;Predictions are how you predict an output f(x) given input features, weights, and a bias. In linear regression, the predicted output is computed as:&lt;br&gt;


&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;fw,b(x(i))=wx(i)+b/𝑊⋅𝑋+𝑏
 f_{w,b}(x^{(i)}) = wx^{(i)} + b / 𝑊⋅𝑋 + 𝑏
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;w&lt;/span&gt;&lt;span class="mpunct mtight"&gt;,&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mopen mtight"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;span class="mclose mtight"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mopen mtight"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;span class="mclose mtight"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mord"&gt;/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;W&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;X&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;W is the weight vector (one weight per feature, since we have three features, then the weight would be a vector of three values)&lt;/li&gt;
&lt;li&gt;X is the input feature vector&lt;/li&gt;
&lt;li&gt;b is the bias (intercept term)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The training process aims to find the appropriate weights and bias that, when applied to new input values, produce accurate predictions. Essentially, training is about learning these optimal parameters (weights and bias) for future use on new data points.&lt;/p&gt;

&lt;p&gt;The process of finding optimal weights and bias involves:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Initializing the parameters (weights and bias) with random values&lt;/li&gt;
&lt;li&gt;Making predictions using the current parameters&lt;/li&gt;
&lt;li&gt;Calculating the prediction error using a loss function and storing the result&lt;/li&gt;
&lt;li&gt;Updating the weights and bias to new values using gradient descent&lt;/li&gt;
&lt;li&gt;Repeating steps 2-4 for multiple training epochs&lt;/li&gt;
&lt;li&gt;Monitoring the loss over time—decreasing values indicate the model is learning and converging.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This process yields trained parameters (weights and bias) that can make accurate predictions on new data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def predict(
    X: np.ndarray, 
    W: np.ndarray, 
    b: float
) -&amp;gt; np.ndarray:
    """
    Predict target values using linear regression.

    Args:
        X (np.ndarray): Feature matrix of shape (n_samples, n_features)
        W (np.ndarray): Weight vector of shape (n_features,)
        b (float): Bias term

    Returns:
        np.ndarray: Predicted values of shape (n_samples,)
    """

    # Calculate predictions using the linear regression formula: f(x) = X·W + b
    # - np.dot(X, W) computes the matrix multiplication between features and weights
    # - Adding b applies the bias term to each prediction
    f_x = np.dot(X, W) + b

    return f_x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;f_x = np.dot(X, W) + b uses Vectorization to compute f(x).&lt;/p&gt;
&lt;h2&gt;
  
  
  Loss
&lt;/h2&gt;

&lt;p&gt;Next, we would compute the loss. Loss refers to the difference between the predicted values and the actual (true) values of the target variable. It quantifies how well or poorly the model is performing.&lt;br&gt;
The loss function quantifies how far our predictions are from the actual values. Low loss values indicate good model performance, while high loss values suggest the model needs improvement.&lt;br&gt;
We’ll use mean squared error (MSE) as the loss function. It’s defined as:&lt;br&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;J(w,b)=12m∑i=0m−1(fw,b(x(i))−y(i))2
 J(w,b) = \frac{1}{2m} \sum\limits_{i = 0}^{m-1} (f_{w,b}(x^{(i)}) - y^{(i)})^2
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;J&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mop op-limits"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;span class="mrel mtight"&gt;=&lt;/span&gt;&lt;span class="mord mtight"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="mop op-symbol large-op"&gt;∑&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;m&lt;/span&gt;&lt;span class="mbin mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;w&lt;/span&gt;&lt;span class="mpunct mtight"&gt;,&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mopen mtight"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;span class="mclose mtight"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mopen mtight"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;span class="mclose mtight"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def mean_squared_loss(
    X: np.ndarray, 
    y: np.ndarray, 
    W: np.ndarray, 
    b: float
) -&amp;gt; float:
    """
    Compute the mean squared error loss.

    Args:
        X (np.ndarray): Feature matrix of shape (m, n)
        y (np.ndarray): Target vector of shape (m,)
        W (np.ndarray): Weight vector of shape (n,)
        b (float): Bias term

    Returns:
        float: Mean squared error loss
    """

    # Get the number of training examples
    m = X.shape[0]

    # Calculate predictions using the predict function
    predictions = predict(X, W, b) 

    # Compute the squared differences between predictions and actual values
    squared_errors = (predictions - y) ** 2

    # Calculate the mean squared error loss with the 1/2m factor
    loss = np.sum(squared_errors) / (2 * m)

    return loss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Gradient and Gradient Descent
&lt;/h2&gt;

&lt;p&gt;Next, we will compute a gradient. This calculates how much we need to change the weights and bias to reduce prediction error, helping the model learn during training.&lt;br&gt;
The gradient is defined as:&lt;br&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;∂J(w,b)∂w=1m∑i=0m−1(fw,b(x(i))−y(i))x(i)
 \frac{\partial J(w,b)}{\partial w}  = \frac{1}{m} \sum\limits_{i = 0}^{m-1} (f_{w,b}(x^{(i)}) - y^{(i)})x^{(i)}
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;∂&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;∂&lt;/span&gt;&lt;span class="mord mathnormal"&gt;J&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mop op-limits"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;span class="mrel mtight"&gt;=&lt;/span&gt;&lt;span class="mord mtight"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="mop op-symbol large-op"&gt;∑&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;m&lt;/span&gt;&lt;span class="mbin mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;w&lt;/span&gt;&lt;span class="mpunct mtight"&gt;,&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mopen mtight"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;span class="mclose mtight"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mopen mtight"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;span class="mclose mtight"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mopen mtight"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;span class="mclose mtight"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;




&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;∂J(w,b)∂b=1m∑i=0m−1(fw,b(x(i))−y(i))
 \frac{\partial J(w,b)}{\partial b}  = \frac{1}{m} \sum\limits_{i = 0}^{m-1} (f_{w,b}(x^{(i)}) - y^{(i)})
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;∂&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;∂&lt;/span&gt;&lt;span class="mord mathnormal"&gt;J&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mop op-limits"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;span class="mrel mtight"&gt;=&lt;/span&gt;&lt;span class="mord mtight"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="mop op-symbol large-op"&gt;∑&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;m&lt;/span&gt;&lt;span class="mbin mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;w&lt;/span&gt;&lt;span class="mpunct mtight"&gt;,&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mopen mtight"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;span class="mclose mtight"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mopen mtight"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;span class="mclose mtight"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def compute_gradient(
    X: np.ndarray, 
    y: np.ndarray, 
    W: np.ndarray, 
    b: float
) -&amp;gt; tuple[np.ndarray, float]:
    """
    Compute the gradient of the cost function with respect to parameters W and b.

    Args:
        X: Input features, shape (m, n) where m is number of examples and n is number of features
        y: Target values, shape (m,)
        W: Weight parameters, shape (n,)
        b: Bias parameter

    Returns:
        tuple: Gradients with respect to W and b
            - d_dw: Gradient with respect to W, shape (n,)
            - d_db: Gradient with respect to b, scalar
    """

    # Get the number of examples (m) and features (n)
    m, n = X.shape

    # Calculate model predictions using current parameters
    predictions = predict(X, W, b) 
    # Compute the error (difference between predictions and actual values)
    error = predictions - y

    # Calculate gradient for weights by taking dot product of X transpose and error, then normalize by m
    # This is the partial derivative of the cost function with respect to W
    d_dw = np.dot(X.T, error) / m

    # Calculate gradient for bias by summing all errors and normalizing by m
    # This is the partial derivative of the cost function with respect to b
    d_db = np.sum(error) / m

    return d_dw, d_db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;After this, we create the gradient descent function that enables us to perform one step of gradient descent to update model parameters.&lt;br&gt;
The formula used to update the model's parameters is as follows:&lt;br&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;w=w−α∂J(w,b)∂w
 w = w -  \alpha \frac{\partial J(w,b)}{\partial w} 
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;α&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;∂&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;∂&lt;/span&gt;&lt;span class="mord mathnormal"&gt;J&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;



&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;b=b−α∂J(w,b)∂b
 b = b -  \alpha \frac{\partial J(w,b)}{\partial b}
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;α&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;∂&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;∂&lt;/span&gt;&lt;span class="mord mathnormal"&gt;J&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def gradient_descent(
    X: np.ndarray, 
    y: np.ndarray, 
    W: np.ndarray, 
    b: float, 
    learning_rate: float
)-&amp;gt; tuple[np.ndarray, float]:
    """
    Perform one step of gradient descent to update model parameters.

    Args:
        X: Input features, shape (m, n) where m is number of examples and n is number of features
        y: Target values, shape (m,) or (m, 1)
        W: Current weight parameters, shape (n,) or (n, 1)
        b: Current bias parameter
        learning_rate: Step size for the gradient descent update

    Returns:
        tuple: Updated weights W and bias b after one step of gradient descent
    """

    # Calculate gradients for weights and bias using current parameters
    dW, db = compute_gradient(X, y, W, b)

    # Update weights by subtracting the learning rate multiplied by the gradient
    W =  W - (learning_rate * dW)
    # Update bias by subtracting the learning rate multiplied by the gradient
    b = b - (learning_rate * db)

    return W, b   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Model Training
&lt;/h2&gt;

&lt;p&gt;Now that we have implemented the core functionalities needed, i.e., prediction, loss, gradient computation, and training parameter updates, we can train our linear regression model using gradient descent.&lt;br&gt;
The training process involves:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Calculating the loss using the current weights and bias (this predicts the output and then computes the MSE)&lt;/li&gt;
&lt;li&gt;Updating the model parameters (weights and bias) using gradient descent&lt;/li&gt;
&lt;li&gt;Repeating the process for the specified number of epochs (training steps)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We store the loss over time so that we can plot it. If the loss decreases over the epochs, we can say the model is converging and learning. If it keeps increasing, then the model is performing poorly, and we need to investigate the cause, since the loss should decrease during proper training.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def train(
    X_train: np.ndarray, 
    y_train: np.ndarray, 
    X_val: np.ndarray,
    y_val: np.ndarray,
    W: np.ndarray, 
    b: float, 
    learning_rate: float, 
    epochs: int
) -&amp;gt; tuple[np.ndarray, float, list[float], list[float]]:
    """
    Train a linear model using gradient descent optimization.

    Args:
        X_train: Training features, shape (n_samples, n_features)
        y_train: Training target values, shape (n_samples,)
        X_val: Validation features, shape (n_samples, n_features)
        y_val: Validation target values, shape (n_samples,)
        W: Initial weight matrix, shape (n_features,)
        b: Initial bias term
        learning_rate: Step size for gradient descent updates
        epochs: Number of training iterations

    Returns:
        tuple: Updated weights W, bias b, train loss history, and validation loss history after training
    """

    # Initialize empty lists to store loss values during training
    train_loss_history = []
    val_loss_history = []

    # Iterate through the specified number of training epochs
    for epoch in range(epochs):
        # Calculate and store the mean squared loss on training data
        train_loss = mean_squared_loss(X_train, y_train, W, b)
        train_loss_history.append(train_loss)

        # Calculate and store the mean squared loss on validation data
        val_loss = mean_squared_loss(X_val, y_val, W, b)
        val_loss_history.append(val_loss)      

        # Print progress every 100 epochs
        if epoch % 100 == 0:
            print(f"Epoch {epoch}: Train Loss = {train_loss:.4f}, Val Loss = {val_loss:.4f}")

        # Update model parameters (weights and bias) using gradient descent
        W, b = gradient_descent(X_train, y_train, W, b, learning_rate)

    # Return the trained model parameters and loss histories
    return W, b, train_loss_history, val_loss_history
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have our train function in place, our next step is to run it. We will initialize the weights and bias to zero, use a learning rate of 0.01, and run this process 1000 times.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Initialize weights and bias
W = np.zeros(X_train.shape[1])  # shape (n_features,)
b = 0.0
learning_rate = 0.01  # Step size for gradient descent
epochs = 1000  # Number of training iterations

# Train the linear regression model
W_trained, b_trained, train_losses, val_losses = train(X_train_norm, y_train, X_val_norm, y_val, W, b, learning_rate, epochs)

# Print the final trained parameters
print(f"Training parameters Weight: {W_trained}, bias {b_trained}")

# Visualize the training and validation loss over epochs
# This helps to monitor model convergence and potential overfitting
utils.plot_loss_curve(train_losses, val_losses)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0vj25hvz4huq7j1bbzoe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0vj25hvz4huq7j1bbzoe.png" alt="Training Process with loss history"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the final weights are [ 3.78713104  2.88855073 -0.14126015], and the bias is 13.92606568567291.&lt;br&gt;
Note: In our case, the model converged after 200 steps, with no further significant change in the loss. We could modify the training process to implement early stopping based on a patience threshold—I'll leave that as an exercise for you.&lt;/p&gt;
&lt;h2&gt;
  
  
  Testing The Trained Model
&lt;/h2&gt;

&lt;p&gt;We can now use these learned parameters to make predictions on our test dataset.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Make predictions on the test set using trained weights and bias
y_predict = predict(X_test_norm, W_trained, b_trained)

# Calculate the mean squared loss on the test set
y_predict_loss = mean_squared_loss(X_test_norm, y_test, W_trained, b_trained)   

# Print the test loss
print(f"Test Loss: {y_predict_loss}")

# Create a plot comparing actual vs predicted sales
utils.plot_predictions(y_test, y_predict, 'Predicted vs Actual Sales', 'Actual Sales', 'Predicted Sales')

# Print the first 25 actual and predicted values for comparison
for i in range(25):
    print("Print actual va predicted values")
    print(f"Actual: {y_test[i]}, Predicted: {y_predict[i]:.1f}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3sljqs5134uye54l5n8x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3sljqs5134uye54l5n8x.png" alt="Predicted vs Actual Output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The test loss is 1.129492604788525, which shows that our model did very well in predicting the outcome. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we built a complete linear regression model from scratch without relying on high-level machine learning libraries. We walked through each fundamental step from loading and preprocessing a real-world dataset to implementing the prediction and loss functions, computing gradients, and training with gradient descent.&lt;/p&gt;

&lt;p&gt;Along the way, we used the advertising dataset to model the relationship between advertising spend and product sales. By manually implementing each component, we gained a clearer understanding of how linear regression works under the hood.&lt;/p&gt;

&lt;p&gt;This hands-on approach reinforces not just the math behind machine learning, but also the practical workflow required to evaluate and test a simple model. &lt;/p&gt;

&lt;p&gt;You typically won't need to implement this from scratch as we did, since packages like scikit-learn and TensorFlow handle the heavy lifting, unless you're developing entirely new ML algorithms. However, as I mentioned earlier, understanding the fundamentals helps you troubleshoot when models are not performing as expected or failing to converge.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://dev.to/jioophoenix/understanding-linear-regression-inside-out-practical-implementation-with-scikit-learn-and-110k"&gt;part two&lt;/a&gt; of this series, I'll show you how to accomplish the same task using scikit-learn and TensorFlow with just a few lines of code. This approach abstracts away the underlying mathematical complexity of linear regression, however the understanding you’ve gained from this article will give you a real appreciation for the work these libraries do behind the scenes. There's still plenty more to explore! Topics like regularization, feature engineering, and others offer fascinating extensions to what we've covered.&lt;/p&gt;

&lt;p&gt;Thanks for following along! If you found this helpful or have questions, feel free to reach out. &lt;a href="https://coff.ee/johnojo" rel="noopener noreferrer"&gt;You can also buy me a coffee&lt;/a&gt; — happy learning!&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>linearregression</category>
      <category>python</category>
      <category>ai</category>
    </item>
    <item>
      <title>Consuming GraphQL API In ASP.NET Core (Part 2)</title>
      <dc:creator>John Ojo</dc:creator>
      <pubDate>Thu, 28 Jan 2021 10:13:05 +0000</pubDate>
      <link>https://dev.to/jioophoenix/consuming-graphql-api-in-asp-net-core-part-2-55ga</link>
      <guid>https://dev.to/jioophoenix/consuming-graphql-api-in-asp-net-core-part-2-55ga</guid>
      <description>&lt;p&gt;Here's the second part of the post &lt;a href="https://dev.to/jioophoenix/hotchocolate-introduction-to-graphql-for-asp-net-core-part-1-2e27"&gt;HotChocolate: Introduction to GraphQL for ASP.NET Core (Part 1)&lt;/a&gt;. In part 1, we developed a GraphQL API using ASP.NET. In this part, we will focus on consuming the endpoint in an ASP.NET Blazor WebAssembly application. &lt;/p&gt;

&lt;p&gt;We will create a page that will display all the Employees along-side their Department, another page that displays a single Employee and a page with a form to create an Employee.&lt;/p&gt;

&lt;p&gt;The code for this sample can be found on the &lt;a href="https://github.com/CloudBloq/GraphQLSampleAppUI" rel="noopener noreferrer"&gt;CloudBloq/GraphQLSampleAppUI&lt;/a&gt; repository on GitHub. &lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://visualstudio.microsoft.com/vs/" rel="noopener noreferrer"&gt;Visual Studio 2019 (version 16.8.0 upwards)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Create the Solution and Project
&lt;/h2&gt;

&lt;p&gt;After opening VS, click the Create a new project link then search for &lt;strong&gt;Blazor&lt;/strong&gt; and select it:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8u8ugcenb9plri45j0x2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8u8ugcenb9plri45j0x2.jpg" alt="BlazorSearch" width="619" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Give the project and solution a name &lt;strong&gt;GraphQLSampleAppUI&lt;/strong&gt; then click &lt;strong&gt;create&lt;/strong&gt;:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffvt4c08p1r5sepabsolg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffvt4c08p1r5sepabsolg.jpg" alt="NameProAndSolu" width="800" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the Blazor WebAssembly App option then click &lt;strong&gt;create&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjj5dn2bd88b141i9i1o6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjj5dn2bd88b141i9i1o6.jpg" alt="Template" width="800" height="558"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Install Dependencies
&lt;/h2&gt;

&lt;p&gt;We will make use of &lt;a href="https://github.com/graphql-dotnet/graphql-client" rel="noopener noreferrer"&gt;GraphQL.Client(v 3.2.0)&lt;/a&gt; library to consume the GraphQL API. To install the package, right click the solution in the solution explorer and select &lt;strong&gt;Manage NuGet Packages for Solution&lt;/strong&gt;. Under the Browse section, search for &lt;strong&gt;GraphQL.Client&lt;/strong&gt; and click on it, then in the preview panel click the Install button:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuzje2peylc1lz7l73cv1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuzje2peylc1lz7l73cv1.jpg" alt="Client" width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, install the &lt;strong&gt;modernhttpclient&lt;/strong&gt; and &lt;strong&gt;GraphQL.Client.Serializer.Newtonsoft&lt;/strong&gt; packages respectively.&lt;/p&gt;
&lt;h2&gt;
  
  
  Consume The API
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://dev.to/jioophoenix/hotchocolate-introduction-to-graphql-for-asp-net-core-part-1-2e27"&gt;part 1&lt;/a&gt;, to test the Query or Mutation, we used Banana Cake Pop:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftufie63htcef6a1h9jm1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftufie63htcef6a1h9jm1.jpg" alt="mutation" width="800" height="431"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuv1pckpepzr9t3b6bz7z.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuv1pckpepzr9t3b6bz7z.jpg" alt="query1" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, we will make use of the &lt;a href="https://github.com/graphql-dotnet/graphql-client" rel="noopener noreferrer"&gt;GraphQL.Client&lt;/a&gt; library to consume the GraphQL API. We will write all the code required to perform the Query and Mutation in a folder. Add a new folder called &lt;strong&gt;DataAccess&lt;/strong&gt;. &lt;/p&gt;
&lt;h3&gt;
  
  
  Query
&lt;/h3&gt;

&lt;p&gt;We will create a generic method that can be used to perform all the Query we need to perform. In the &lt;strong&gt;DataAccess&lt;/strong&gt; folder, add a new C# class file called &lt;strong&gt;Query.cs&lt;/strong&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The way &lt;a href="https://github.com/graphql-dotnet/graphql-client" rel="noopener noreferrer"&gt;GraphQL.Client&lt;/a&gt; works is to first create an instance of &lt;strong&gt;GraphQLHttpClient&lt;/strong&gt; using an instance of &lt;strong&gt;GraphQLHttpClientOptions&lt;/strong&gt; (which takes in the URI of the GraphQL Server) then use an instance of the &lt;strong&gt;GraphQLRequest&lt;/strong&gt; to create the Query or the Mutation string that will be sent to the Server.&lt;/p&gt;

&lt;p&gt;Line 15 defines the field graphQLHttpClient of type GraphQLHttpClient. Line 26 assigns a new instance (using an instance of GraphQLHttpClientOptions) to the graphQLHttpClient field. The other parameter is used to specify the deserializer used to deserialize the output. &lt;/p&gt;

&lt;p&gt;Note that if you modified line 8 in &lt;a href="https://github.com/CloudBloq/GraphQLSampleApp/blob/master/GraphQLSampleApp/Properties/launchSettings.json#L8" rel="noopener noreferrer"&gt;launchSettings.json&lt;/a&gt; in &lt;a href="https://dev.to/jioophoenix/hotchocolate-introduction-to-graphql-for-asp-net-core-part-1-2e27"&gt;part 1&lt;/a&gt;, you also have to modify line 19 here. &lt;/p&gt;

&lt;p&gt;Lines 30 to 54 define the generic method &lt;strong&gt;ExceuteQueryReturnListAsyn&lt;/strong&gt;. The generic type &lt;strong&gt;T&lt;/strong&gt; is the type the output will be deserialized into. The parameter &lt;strong&gt;graphQLQueryType&lt;/strong&gt; is the Query type and the parameter &lt;strong&gt;completeQueryString&lt;/strong&gt; will contain the complete Query. From the example below, graphQLQueryType will be allDepartmentsWithEmployee and completeQueryString will be the entire string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;allDepartmentsWithEmployee&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In line 34, an instance of &lt;strong&gt;GraphQLRequest&lt;/strong&gt; is created which takes in the complete query string. The Query is sent to the server in line 39. The result gotten from the server will contain the Query type in the beginning so we replace it with an empty string in line 42. The output is deserialized in line 46 to the generic type. &lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;ExceuteQueryReturnListAsyn&lt;/strong&gt; is used when the output we are expecting is an array of the generic type. The other method &lt;strong&gt;ExceuteQueryAsyn&lt;/strong&gt; in line 56 is the same as &lt;strong&gt;ExceuteQueryReturnListAsyn&lt;/strong&gt; except that it should be used when we are expecting a single object of the generic type as the output. The &lt;strong&gt;ExceuteQueryReturnListAsyn&lt;/strong&gt; and &lt;strong&gt;ExceuteQueryAsyn&lt;/strong&gt; methods can be used to perform any Query we need and deserialize the output accordingly. &lt;/p&gt;
&lt;h3&gt;
  
  
  Mutation
&lt;/h3&gt;

&lt;p&gt;In the &lt;strong&gt;DataAccess&lt;/strong&gt; folder, add a new C# class file called &lt;strong&gt;Mutation.cs&lt;/strong&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;This code in this class follows the same pattern as the &lt;strong&gt;Query.cs&lt;/strong&gt;. Line 27 defines the generic method &lt;strong&gt;ExceuteMutationAsyn&lt;/strong&gt;, it takes in the same parameter as the &lt;strong&gt;ExceuteQueryAsyn&lt;/strong&gt;, sends the Mutation to the server and deserializes the output to the generic type T.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Models
&lt;/h2&gt;

&lt;p&gt;We will need the models that the Query and Mutation output will be deserialized into. Add a new folder &lt;strong&gt;Model&lt;/strong&gt; in the &lt;strong&gt;DataAccess&lt;/strong&gt; folder. Add a new C# class &lt;strong&gt;Employee.cs&lt;/strong&gt; to the &lt;strong&gt;Model&lt;/strong&gt; folder:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Add another C# class file &lt;strong&gt;Department.cs&lt;/strong&gt; to the &lt;strong&gt;Model&lt;/strong&gt; folder:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We need another model that will be used for the form used to create an Employee. Add another C# class file &lt;strong&gt;CreateEmployeeModel.cs&lt;/strong&gt; to the &lt;strong&gt;Model&lt;/strong&gt; folder:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
The validations added to the properties (Required, EmailAddress...) via attributes will be used by the form to validate the input.

&lt;p&gt;We need another model that will be used to hold the output of response when we create an Employee. Add another C# class file &lt;strong&gt;CreateEmployeeReturnModel.cs&lt;/strong&gt; to the &lt;strong&gt;Model&lt;/strong&gt; folder:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Blazor Pages
&lt;/h2&gt;

&lt;p&gt;First, we will create the page that will be used to display all the Employees. In the &lt;strong&gt;Pages&lt;/strong&gt; folder, add a new Razor Component called &lt;strong&gt;EmployeeView.razor&lt;/strong&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The variable AllEmployees on line 43 is used to store the Employees. You see how I called the &lt;strong&gt;ExceuteQueryReturnListAsyn&lt;/strong&gt; passing in the type &lt;strong&gt;Employee&lt;/strong&gt; and the parameters. The variable AllEmployees is checked first if it contains any item on line 13, if it does then the data is displayed in the table in lines 19 to 39. &lt;/p&gt;

&lt;p&gt;Next, we will create the page that will be used to display the individual Employee detail. In the &lt;strong&gt;Pages&lt;/strong&gt; folder, add a new Razor Component called &lt;strong&gt;ViewEmployee.razor&lt;/strong&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The &lt;strong&gt;ExceuteQueryAsyn&lt;/strong&gt; method is used to get the Employee details in line 54. The Id is gotten from the URI and is attached to the string sent to the server in line 51. &lt;/p&gt;

&lt;p&gt;Next, we will create the page that will be used to create an Employee. In the &lt;strong&gt;Pages&lt;/strong&gt; folder, add a new Razor Component called &lt;strong&gt;CreateEmployee.razor&lt;/strong&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Lines 12 to 33 define the form used to receive the data. The form uses the model &lt;strong&gt;CreateEmployeeModel&lt;/strong&gt; via the variable createEmployee. The method &lt;strong&gt;ExceuteMutationAsyn&lt;/strong&gt; is called on line 56, and the type &lt;strong&gt;CreateEmployeeReturnModel&lt;/strong&gt; is passed as the return type. Notice how the form data is bound to the string on line 53.&lt;/p&gt;

&lt;p&gt;Finally, we need to modify the &lt;strong&gt;NavMenu.razor&lt;/strong&gt; in the &lt;strong&gt;Shared&lt;/strong&gt; folder:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Running the Application
&lt;/h2&gt;

&lt;p&gt;Ensure the GraphQL server &lt;a href="https://localhost:44351/graphql/" rel="noopener noreferrer"&gt;https://localhost:44351/graphql/&lt;/a&gt; is running first. Right-click the solution and click Build Solution. After Build is successful, click CTRL + f5 or f5 to run the application. You should get:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0fff10kjzr87xewaix0w.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0fff10kjzr87xewaix0w.jpg" alt="run1" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you click the &lt;strong&gt;Employee&lt;/strong&gt; link, you should get:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhpyovklf8b4ca6leurve.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhpyovklf8b4ca6leurve.jpg" alt="run2" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;Create an Employee&lt;/strong&gt; link and try to click the Create button without entering any data in the form, you should get the response:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkzrb5yp5oc0nos6hairv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkzrb5yp5oc0nos6hairv.jpg" alt="run3" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you enter an invalid email or an age that isn't between 20 and 50, you should get the validation failed error.&lt;/p&gt;

&lt;p&gt;This isn't the end of learning Blazor and GraphQL. There are a lot of things to explore, especially in Blazor WebAssembly. The links below will help you if you are really interested in learning more:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://app.pluralsight.com/library/courses/getting-started-blazor/table-of-contents?aid=7010a000002LUv2AAG" rel="noopener noreferrer"&gt;Blazor: Getting Started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://app.pluralsight.com/library/courses/building-graphql-apis-aspdotnet-core/table-of-contents?aid=7010a000002LUv2AAG" rel="noopener noreferrer"&gt;Building GraphQL APIs with ASP.NET Core&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Awesome! Please share it with anyone you think could use this information. Thanks for reading. As always, if you have any questions, comments, or concerns about this post, feel free to leave a comment below.&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>dotnet</category>
      <category>netcore</category>
    </item>
    <item>
      <title>HotChocolate: Introduction to GraphQL for ASP.NET Core (Part 1)</title>
      <dc:creator>John Ojo</dc:creator>
      <pubDate>Mon, 04 Jan 2021 10:38:07 +0000</pubDate>
      <link>https://dev.to/jioophoenix/hotchocolate-introduction-to-graphql-for-asp-net-core-part-1-2e27</link>
      <guid>https://dev.to/jioophoenix/hotchocolate-introduction-to-graphql-for-asp-net-core-part-1-2e27</guid>
      <description>&lt;p&gt;In this post, I will walk you through how to get started with GraphQL in ASP.NET Core using HotChocolate.&lt;br&gt;
In this part, we will only focus on GraphQL Server, configuring it with ASP.NET Core. &lt;br&gt;
In &lt;a href="https://dev.to/jioophoenix/consuming-graphql-api-in-asp-net-core-part-2-55ga"&gt;part 2&lt;/a&gt;, We will focus on integrating the GraphQL endpoint into a Blazor WebAssembly application.&lt;/p&gt;
&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://graphql.org/learn/" rel="noopener noreferrer"&gt;GraphQL&lt;/a&gt; is a query language for your API, and a server-side runtime for executing queries by using a type system you define for your data. It lets you specify exactly what data you need.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/ChilliCream/hotchocolate-docs/tree/master/docs" rel="noopener noreferrer"&gt;HotChocolate&lt;/a&gt; is a .NET GraphQL platform that can help you build a GraphQL layer over your existing and new application. HotChocolate is very easy to set up and takes the clutter away from writing GraphQL schemas.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We will create a simple application that can be used to &lt;strong&gt;Create&lt;/strong&gt;, &lt;strong&gt;Read&lt;/strong&gt;, &lt;strong&gt;Update&lt;/strong&gt; and &lt;strong&gt;Delete&lt;/strong&gt; an Employee together with a department. &lt;/p&gt;

&lt;p&gt;The code for this sample can be found on the &lt;a href="https://github.com/CloudBloq/GraphQLSampleApp" rel="noopener noreferrer"&gt;CloudBloq/GraphQLSampleApp&lt;/a&gt; repository on GitHub.&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://visualstudio.microsoft.com/vs/" rel="noopener noreferrer"&gt;Visual Studio 2019 (version 16.8.0 upwards)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.microsoft.com/en-us/sql-server/sql-server-downloads" rel="noopener noreferrer"&gt;SQL Server 2019&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The Database
&lt;/h2&gt;

&lt;p&gt;The database schema and data script can be found in the folder &lt;a href="https://github.com/CloudBloq/GraphQLSampleApp/tree/master/GraphQLSampleApp/Script" rel="noopener noreferrer"&gt;CloudBloq/GraphQLSampleApp/tree/master/GraphQLSampleApp/Script&lt;/a&gt;. Ensure to run the script in &lt;a href="https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver15" rel="noopener noreferrer"&gt;SQL Server Management Studio&lt;/a&gt; or in Visual Studio &lt;strong&gt;SQL Server Object Explore&lt;/strong&gt; to set up the Database and tables.&lt;/p&gt;
&lt;h2&gt;
  
  
  Create the Solution and Project
&lt;/h2&gt;

&lt;p&gt;We will need an ASP.NET Web API project. After opening VS, click the &lt;strong&gt;Create a new project&lt;/strong&gt; link and select the &lt;strong&gt;ASP.NET Core Web Application&lt;/strong&gt;, give the project a name &lt;strong&gt;GraphQLSampleApp&lt;/strong&gt; and the solution a name &lt;strong&gt;GraphQLSampleApp&lt;/strong&gt; click &lt;strong&gt;Create&lt;/strong&gt;. Next, select the &lt;strong&gt;API&lt;/strong&gt;, then click &lt;strong&gt;Create&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Install Dependencies
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We need to install the &lt;a href="https://chillicream.com/" rel="noopener noreferrer"&gt;HotChocolate.AspNetCore(v11.0.2)&lt;/a&gt; package. The package contains the GraphQL API's for ASP.NET. To install the package, right click the solution in the solution explorer and select &lt;strong&gt;Manage NuGet Packages for Solution&lt;/strong&gt;. Under the Browse section, search for &lt;strong&gt;HotChocolate.AspNetCore&lt;/strong&gt; and click on it, then in the preview panel click the Install button:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fijcahpsnsstnmjev93wi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fijcahpsnsstnmjev93wi.jpg" alt="nugetpackage" width="800" height="344"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Also, install the &lt;strong&gt;Microsoft.EntityFrameworkCore&lt;/strong&gt;, &lt;strong&gt;Microsoft.EntityFrameworkCore.SqlServer&lt;/strong&gt; and &lt;strong&gt;Microsoft.EntityFrameworkCore.Tools&lt;/strong&gt; packages respectively.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The Entities
&lt;/h2&gt;

&lt;p&gt;We will make use of &lt;a href="https://www.entityframeworktutorial.net/efcore/entity-framework-core.aspx" rel="noopener noreferrer"&gt;EntityFrameworkCore&lt;/a&gt; as the ORM. Entities (classes) are used to define the database objects (tables) and those entities are mapped to the database table in the &lt;a href="https://www.entityframeworktutorial.net/efcore/entity-framework-core-dbcontext.aspx" rel="noopener noreferrer"&gt;DbContext&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;We will define two Entities, one for the &lt;strong&gt;Department&lt;/strong&gt; and the other for the &lt;strong&gt;Employee&lt;/strong&gt; tables.&lt;br&gt;
We will keep everything simple by using folders to hold the data access code, the GraphQL code and the Database Entities. In a real application, a Class library would be better for the different layers.&lt;/p&gt;

&lt;p&gt;Create a folder called &lt;strong&gt;DataAccess&lt;/strong&gt; in the &lt;strong&gt;GraphQLSampleApp&lt;/strong&gt; project, create another folder called &lt;strong&gt;Entity&lt;/strong&gt; inside the &lt;strong&gt;DataAccess&lt;/strong&gt; folder. &lt;/p&gt;
&lt;h3&gt;
  
  
  Department Entity
&lt;/h3&gt;

&lt;p&gt;Add a C# Class file called &lt;strong&gt;Department.cs&lt;/strong&gt; to the &lt;strong&gt;Entity&lt;/strong&gt; folder. This class will be used to define the &lt;strong&gt;Department&lt;/strong&gt; entity. The code for this file is:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Line 9 is used to mark the DepartmentId property as the primary key of the entity, line 10 is used to ensure that the value of the DepartmentId is unique and auto generated if it is not provided by the user. Line 15 is used to define a relationship (navigation property) between the Department and Employee entity. The relationship:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;ICollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Employees&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;means that a single Department can have many Employees assigned to it. This line will throw an error now unless you have created the Employee entity earlier.&lt;/p&gt;
&lt;h3&gt;
  
  
  Employee Entity
&lt;/h3&gt;

&lt;p&gt;Add another C# class to the &lt;strong&gt;Entity&lt;/strong&gt; folder called &lt;strong&gt;Employee.cs&lt;/strong&gt;. After adding this class, the error gotten earlier in &lt;strong&gt;Department.cs&lt;/strong&gt; will no longer be there. The code for this file is:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Line 24 defines the foreign key property used to link an Employee to his/her department. Line 25 defines the navigation property that states that an Employee can only have one department. &lt;/p&gt;

&lt;h3&gt;
  
  
  The DbContext
&lt;/h3&gt;

&lt;p&gt;The DbContext will be simple and straight forward. In a real application, most of the database configurations are done in this file. Add a new C# Class file to the &lt;strong&gt;Entity&lt;/strong&gt; folder, name it &lt;strong&gt;SampleAppDbContext.cs&lt;/strong&gt;. The code for this file is:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Line 11 defines the Employee property which is used to map the Employee.cs entity to the Employee table in the database. Line 13 defines the Department property which is used to map the Department.cs entity to the Department table in the database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Repositories
&lt;/h2&gt;

&lt;p&gt;Next, we will write the layer that will send and receive data to and from the database. In the &lt;strong&gt;DataAccess&lt;/strong&gt; folder, add another folder called &lt;strong&gt;DAO&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Department Repository
&lt;/h3&gt;

&lt;p&gt;Add a C# class file called &lt;strong&gt;DepartmentRepository.cs&lt;/strong&gt; to the &lt;strong&gt;DAO&lt;/strong&gt; folder:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Lines 19 to 22 define the GetAllDepartmentOnly() method which is used to return a list of all the Departments.&lt;br&gt;
Lines 24 to 29 define the GetAllDepartmentsWithEmployee() method which returns all the Departments along-side the Employee(s) in each Department. The navigation property defined in line 15 in &lt;strong&gt;Department.cs&lt;/strong&gt; made it possible to return the Departments along-side the Employee(s).&lt;br&gt;
Lines 31 to 36 define the CreateDepartment() method which takes in a new Department and adds it to the database.&lt;/p&gt;
&lt;h3&gt;
  
  
  Employee Repository
&lt;/h3&gt;

&lt;p&gt;Add a C# class file called &lt;strong&gt;EmployeeRepository.cs&lt;/strong&gt; to the &lt;strong&gt;DAO&lt;/strong&gt; folder:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This class defines the GetEmployees() which returns a list of all the Employees, the GetEmployeeById() which takes an Id and returns the Employee only if the Id is valid and exists, the GetEmployeesWithDepartment() which returns a list of all the Employees along-side the Department, and the CreateEmployee() which takes in an Employee and adds them to the database.&lt;/p&gt;

&lt;h2&gt;
  
  
  GraphQL
&lt;/h2&gt;

&lt;p&gt;If you are familiar with REST API, we use GET to fetch data from the data store, we use POST, PUT DELETE to modify the state of data. GET in REST API is same as Query in GraphQL. POST, PUT, DELETE, is same as Mutation. In GraphQL, there is also Subscription which is used to set up event listeners.&lt;/p&gt;

&lt;h3&gt;
  
  
  Query
&lt;/h3&gt;

&lt;p&gt;Add a new C# class file called &lt;strong&gt;Query.cs&lt;/strong&gt; to the &lt;strong&gt;DataAccess&lt;/strong&gt; folder. This class will contain all the Queries we need to perform:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;AllEmployeeOnly() on line 12 returns all the Employees; we inject an instance of the &lt;strong&gt;EmployeeRepository&lt;/strong&gt; into this method by marking the input parameter with the [Service] attribute. AllEmployeeWithDepartment() on line 15 returns the Employees along-side the Department.&lt;br&gt;
Line 18 defines GetEmployeeById(), the parameter &lt;strong&gt;ITopicEventSender eventSender&lt;/strong&gt; is used to create a subscription with Topic "ReturnedEmployee". Anytime this method is called, the event is sent on line 22 and any method that subscribes to this event will receive the data.&lt;/p&gt;
&lt;h3&gt;
  
  
  Mutation
&lt;/h3&gt;

&lt;p&gt;Add a new C# class file called &lt;strong&gt;Mutation.cs&lt;/strong&gt; to the &lt;strong&gt;DataAccess&lt;/strong&gt; folder. This class will contain all the Mutations we need to perform:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Line 15 defines CreateDepartment(). The parameter departmentName will be provided by the user. The parameter ITopicEventSender eventSender is used to create a subscription with Topic "DepartmentCreated".&lt;/p&gt;

&lt;p&gt;Line 29 defines a method CreateEmployeeWithDepartmentId() that can be used to create a new Employee passing in an existing DepartmentId i.e. create an Employee with an existing department. The parameters name: string, age: int, email: string, and departmentId: int will be provided by the user. Notice we set the DepartmentId on line 37 to the departmentId passed by the user.&lt;/p&gt;

&lt;p&gt;Line 44 defines CreateEmployeeWithDepartment(). This method is used to create a new Employee. In the process of creating the Employee, a new Department is created and the DepartmentId property of this Employee is set automatically to the DepartmentId of the newly created Department. Notice how this is done on line 52 by setting the navigation property to a new Department.&lt;/p&gt;

&lt;h3&gt;
  
  
  Subscription
&lt;/h3&gt;

&lt;p&gt;Subscriptions are used to set up event listeners e.g. we can set up an event listener that responds when we create a new Department or Query the database for an Employee etc. Add a new C# class file called &lt;strong&gt;Subscription.cs&lt;/strong&gt; to the &lt;strong&gt;DataAccess&lt;/strong&gt; folder:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;OnDepartmentCreate() on line 17 defines a subscriber of Topic "DepartmentCreated" likewise line 25 defines OnEmployeeGet() a subscriber of Topic "ReturnedEmployee". &lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring GraphQL
&lt;/h2&gt;

&lt;p&gt;We need to configure the application to make use of GraphQL. Replace the code in your Startup.cs with:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Line 32 is used to add the Service for GraphQL, Query, Mutation and Subscription. The AddQueryType(), AddMutationType() and AddSubscriptionType() takes in the Query, Mutation and Subscription classes respectively. &lt;/p&gt;

&lt;p&gt;Line 55 is used to map the endpoint to use GraphQL. &lt;br&gt;
The middleware on line 50 is used to configure the application to ensure the Subscription gives the output. &lt;/p&gt;

&lt;p&gt;Line 27 adds the DbContext service; we configure this service to make use of SQL Server as the database. The connection string is defined in the &lt;strong&gt;appsettings.json&lt;/strong&gt; file as:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Don't forget to change the &lt;strong&gt;Data Source&lt;/strong&gt; value to that of the database you ran the schema and data script in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the Application
&lt;/h2&gt;

&lt;p&gt;Right-click the solution and click Build Solution. After Build is successful, click CTRL + f5 or f5 to run the application. In your browser, navigate to &lt;a href="https://localhost:44351/graphql/" rel="noopener noreferrer"&gt;https://localhost:44351/graphql/&lt;/a&gt;, you should get &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgxv8b02f0vnl89wrt7eq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgxv8b02f0vnl89wrt7eq.jpg" alt="runtime" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;HotChocolate gives you a GraphQL IDE (Banana Cake Pop) right in your browser out of the box, you don't need to install any GraphQL IDE. &lt;/p&gt;

&lt;p&gt;The methods defined in Query.cs, Mutation.cs and Subscription.cs have been categorized under Query, Mutation and Subscription respectively.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test Query
&lt;/h3&gt;

&lt;p&gt;In Banana cake pop, you can add a new tab by clicking the &lt;strong&gt;+&lt;/strong&gt; in the top right corner of the IDE. You can run your schema by clicking the Execute/Play button in the top right corner. Add and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;allDepartmentsWithEmployee&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should get the response in the image below:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftk22fw10ac0f6zndglau.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftk22fw10ac0f6zndglau.jpg" alt="query1" width="800" height="430"&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Try out other Query types, defining the Schema of the data you need.&lt;/p&gt;
&lt;h3&gt;
  
  
  Test Subscription and Query
&lt;/h3&gt;

&lt;p&gt;Add and run the schema below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;subscription&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;onEmployeeGet&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;departmentId&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;    
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1roafldtjlgy2ic13fdt.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1roafldtjlgy2ic13fdt.jpg" alt="sub1" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This Subscribes to the event "ReturnedEmployee" in line 28 of Subscription.cs. You won't get any output yet as shown in the image above, but you can see from the console that we have Subscribed to the event.&lt;/p&gt;

&lt;p&gt;Launch &lt;a href="https://localhost:44351/graphql/" rel="noopener noreferrer"&gt;https://localhost:44351/graphql/&lt;/a&gt; in another browser tab. Next, we will run a Query that will trigger the event. Add and run the below in a new Banana Cake Pop tab in the new browser tab:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;employeeById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe7fczyncnti04yw1keav.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe7fczyncnti04yw1keav.jpg" alt="query22" width="800" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you go back to the first browser tab where we subscribed to the event, you will get the response&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh796nwzq6m7fjqlk9yt9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh796nwzq6m7fjqlk9yt9.jpg" alt="query3" width="800" height="432"&gt;&lt;/a&gt;&lt;br&gt;
If you change the value of the id and run the Query, you will see the changes in the Subscription.&lt;/p&gt;
&lt;h3&gt;
  
  
  Test Mutation
&lt;/h3&gt;

&lt;p&gt;Add and run the schema below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;mutation&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;createEmployeeWithDepartment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"newemp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"newemp@gmail.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;departmentName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mechanical Engr"&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;departmentId&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;departmentId&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;     
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You would get&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffkrzgqj203z8pdcqi2l4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffkrzgqj203z8pdcqi2l4.jpg" alt="mutation" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whoa! We have come to the end of this tutorial. I only added the functions to Create and get an Employee and Department. You are free to explore more and add more functions. &lt;/p&gt;

&lt;p&gt;Awesome! Please share it with anyone you think could use this information. Thanks for reading. As always, if you have any questions, comments, or concerns about this post, feel free to leave a comment below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Yy9wOhiWBJg"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>netcore</category>
      <category>hotchocolate</category>
    </item>
    <item>
      <title>Exploring ASP.NET Web API (.NET 5)</title>
      <dc:creator>John Ojo</dc:creator>
      <pubDate>Thu, 26 Nov 2020 09:30:57 +0000</pubDate>
      <link>https://dev.to/jioophoenix/exploring-asp-net-web-api-net-5-48l</link>
      <guid>https://dev.to/jioophoenix/exploring-asp-net-web-api-net-5-48l</guid>
      <description>&lt;p&gt;.NET 5 is finally out 🎉🥳 and it comes with lots of interesting new features that make software development easier, faster and better. In this article, we will focus on ASP.NET Web API. &lt;/p&gt;

&lt;p&gt;Developing RESTful API using .NET has really improved over the years from ASP.NET MVC to ASP.NET Core and now .NET 5. &lt;br&gt;
Every major release has come with great features that make developing RESTful API better. With .NET 5, it just got a whole lot easier and better by allowing you to focus more on your business logics and creating an Endpoint with few lines of code.&lt;/p&gt;

&lt;p&gt;With .NET 5, you can configure your API to automatically make use of the OpenAPI Support and generate Swagger Docs with just the check of a box (no single line of code is required from you). Isn't it amazing?&lt;/p&gt;

&lt;p&gt;To demonstrate this, we will create an Employee management system that will be used to &lt;strong&gt;Create&lt;/strong&gt;, &lt;strong&gt;Read&lt;/strong&gt;, &lt;strong&gt;Update&lt;/strong&gt; and &lt;strong&gt;Delete&lt;/strong&gt; an Employee's record.&lt;br&gt;
The code for this sample can be found on the &lt;a href="https://github.com/CloudBloq/EmployeeManagement" rel="noopener noreferrer"&gt;CloudBloq/EmployeeManagement&lt;/a&gt; repository on GitHub.&lt;/p&gt;

&lt;p&gt;The technology used in this article are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://cockroachlabs.com/docs/stable/learn-cockroachdb-sql.html" rel="noopener noreferrer"&gt;CockroachDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/aspnet/core/tutorials/web-api-help-pages-using-swagger?view=aspnetcore-5.0" rel="noopener noreferrer"&gt;ASP.NET Core web API documentation with Swagger/OpenAPI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devblogs.microsoft.com/dotnet/announcing-net-5-0/" rel="noopener noreferrer"&gt;Net 5&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://visualstudio.microsoft.com/downloads/" rel="noopener noreferrer"&gt;Visual Studio 2019 (version 16.8 upwards)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cockroachlabs.com/docs/stable/install-cockroachdb-windows.html" rel="noopener noreferrer"&gt;CockroachDB&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Creating the Database
&lt;/h2&gt;

&lt;p&gt;We will make use of CockroachDb to store the data. You can download CockroachDb from &lt;a href="https://www.cockroachlabs.com/docs/stable/install-cockroachdb-windows.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;br&gt;
After starting a &lt;a href="https://www.cockroachlabs.com/docs/v20.1/start-a-local-cluster" rel="noopener noreferrer"&gt;cluster in insecure mode&lt;/a&gt;, we need to &lt;a href="https://www.cockroachlabs.com/docs/v20.1/cockroach-sql.html#start-a-sql-shell" rel="noopener noreferrer"&gt;connect an SQL shell to the cluster in insecure mode&lt;/a&gt;. In the SQL Shell, create a database &lt;strong&gt;employee&lt;/strong&gt; by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Next, point the SQL shell to the newly created database by running:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt; &lt;span class="n"&gt;USE&lt;/span&gt; &lt;span class="n"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Next, create a table &lt;strong&gt;employee&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;gen_random_uuid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;STRING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt; &lt;span class="n"&gt;STRING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="n"&gt;STRING&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;strong&gt;gen_random_uuid()&lt;/strong&gt; is used to tell the DB that if we don't pass in a unique and valid UUID/GUID, it should generate one for us automatically. &lt;/p&gt;

&lt;p&gt;Finally, we will insert a row into the table:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;employee&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Test'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Computer Science'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Test@gmail.com'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can check the data in the table by running:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Create the Solution and Projects
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We will need an ASP.NET Web API project that will define the endpoints.&lt;br&gt;
After opening VS, click the &lt;strong&gt;Create a new project&lt;/strong&gt; link and select the &lt;strong&gt;ASP.NET Core Web Application&lt;/strong&gt;, give the project a name &lt;strong&gt;Employee.API&lt;/strong&gt; and the solution a name &lt;strong&gt;EmployeeManagement&lt;/strong&gt;:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fr39d5lg19116jffspwdi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fr39d5lg19116jffspwdi.jpg" alt="createapi" width="800" height="523"&gt;&lt;/a&gt;&lt;br&gt;
click &lt;strong&gt;Create&lt;/strong&gt;&lt;br&gt;
Next, select the &lt;strong&gt;ASP.NET Core Web API&lt;/strong&gt; and verify that the check box labelled &lt;strong&gt;Enable OpenAPI support&lt;/strong&gt; is checked (see image below):&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fiv974i92kdvmyv1oends.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fiv974i92kdvmyv1oends.jpg" alt="openapicreate" width="800" height="554"&gt;&lt;/a&gt;&lt;br&gt;
click &lt;strong&gt;Create&lt;/strong&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We will make use of a Class Library to define our Database Entity and data access codes. Add a new Class Library (.NET Standard) to the solution named &lt;strong&gt;Employee.DataAccess&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Install Dependencies
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;We need to install the &lt;a href="http://www.npgsql.org/efcore/index.html" rel="noopener noreferrer"&gt;Npgsql.EntityFrameworkCore.PostgreSQL&lt;/a&gt; package. This package will be used to communicate with the database. To install the package, right click the solution in the solution explorer and select &lt;strong&gt;Manage NuGet Packages for Solution&lt;/strong&gt;. Under the Browse section, search for &lt;strong&gt;Npgsql.EntityFrameworkCore.PostgreSQL&lt;/strong&gt; and click on it, then in the preview panel, select the Employee.API and Employee.DataAccess checkbox so it will be installed only into the projects Employee.API and Employee.DataAccess and click the Install button:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F62uo79ii24v61f1coiic.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F62uo79ii24v61f1coiic.jpg" alt="installnosql" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We need to add a reference for project Employee.DataAccess to Employee.API. To do this, right click the Dependencies and click Add project Reference, select the Employee.DataAccess checkbox and click ok.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The Employee Entity
&lt;/h2&gt;

&lt;p&gt;We will make use of &lt;a href="https://www.entityframeworktutorial.net/efcore/entity-framework-core.aspx" rel="noopener noreferrer"&gt;EntityFrameworkCore&lt;/a&gt; as the ORM. Entities (classes) are used to define the database objects (tables) and those entities are mapped to the database table in the &lt;a href="https://www.entityframeworktutorial.net/efcore/entity-framework-core-dbcontext.aspx" rel="noopener noreferrer"&gt;DbContext&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
Create a folder called &lt;strong&gt;Model&lt;/strong&gt; in the &lt;strong&gt;Employee.DataAccess&lt;/strong&gt; project, and in that folder add a new class file called &lt;strong&gt;Employee.cs&lt;/strong&gt;. The naming of this class/entity(Employee.cs) doesn't need to match with the table name(employee), but the property used to map the entity with the table in the DbContext must match. The code in the Employee.cs is:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Four properties (id, name, department and email) are defined to represent the four columns in the employee table. &lt;br&gt;
The [Key] attribute on line 9 is used to specify that the property id is the primary key of the Entity, while the [DatabaseGenerated(DatabaseGeneratedOption.Identity)] attribute on line 10 tells EntityFramework that the value of the primary key will be generated by the database if the User doesn't provide a value. &lt;br&gt;
The [Required] attribute defined on lines 13, 16 and 19 is used to specify that the name, department and email fields are required when sending an Employee's data to the Server via Create or Update; if any of the three is missing, the data for that employee won't be stored in the database. &lt;br&gt;
The [EmailAddress] attribute tells EntityFramework that the value in the email field must be a valid email address.&lt;br&gt;
If you are confused right now, I assure you that after we are done and we run the application, you will see how everything fits into the big picture.&lt;/p&gt;
&lt;h2&gt;
  
  
  Defining the DbContext
&lt;/h2&gt;

&lt;p&gt;The DbContext class is an integral part of Entity Framework. It is used to perform most of the database configurations needed. Add a C# file to the Model folder called &lt;strong&gt;EmployeeManagementDBContext.cs&lt;/strong&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Line 11 define a property (employee) of type DbSet&amp;lt;&amp;gt; which is used to map the Employee object to the employee table. The name of this property must match with the table name else an error will occur. The data in the employee table can now be accessed and manipulated through this property.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessing the Data
&lt;/h2&gt;

&lt;p&gt;Create a new folder called &lt;strong&gt;Repository&lt;/strong&gt; in the project &lt;strong&gt;Employee.DataAccess&lt;/strong&gt;. Next, create an interface called &lt;strong&gt;IEmployeeDAO.cs&lt;/strong&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Line 9 defines the GetAll method which will be used to return a list of all the Employees in the database. Line 13 defines the GetEmployeeById method which takes in the id as a parameter and returns the Employee with that id if one exists. Line 11 defines the CreateEmployee method which takes in a new Employee and adds it to the database. Line 15 defines the method UpdateEmployee which takes in an Employee and updates that record in the database only if the Employee exists in the database.&lt;br&gt;
The delete method is left as an assignment for you, but I will explain what you need to do. &lt;/p&gt;

&lt;p&gt;Next, we will create a concrete class &lt;strong&gt;EmployeeDAO.cs&lt;/strong&gt; that will implement the &lt;strong&gt;IEmployeeDAO.cs&lt;/strong&gt; interface which will then provide implementations to the methods. In the same &lt;strong&gt;Repository&lt;/strong&gt; folder, create a C# class called &lt;strong&gt;EmployeeDAO.cs&lt;/strong&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Line 12 defines a field dbContext of type EmployeeManagementDBContext. Through this field, we can access the &lt;strong&gt;employee&lt;/strong&gt; property hence get access to the employee table data.&lt;/p&gt;

&lt;p&gt;At this point you might be wondering that we haven't added the database connection string to the EmployeeManagementDBContext, but worry not. We will add it in a more secured file in Employee.API. Won't we have to write another set of logics to read the connection string since it will be in a different project? Not at all! One thing you should understand is that at runtime, i.e. when we call an endpoint, the Employee.API will be the &lt;strong&gt;entry point&lt;/strong&gt; of the Http request. At that point, all other libraries (Employee.DataAccess in this case) that are being used by the Employee.API are also executed under the same Http request hence if those libraries need any configuration settings, and such settings aren't present in the library itself but present in the entry point (Employee.API), it will be gotten automatically from the entry point project. Confused? Don't worry. When we get to the Employee.API, you will understand better.&lt;/p&gt;

&lt;p&gt;Lines 38 to 41 provide the implementation to the GetAll method. When we call the property employee of EmployeeManagementDBContext, we get back an object that implements the IQueryable and Enumerable interface. Hence, we are able to run some Linq query against the result. As you can see on line 40, we called the employee and converted the result to a list using the ToList() function. It can be broken down as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;employeeDbResult&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dbContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;employeeDbResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The first line calls the employee property which we then apply the ToList() function on in the second line to convert the result to a List. Those 2 lines of code perform the same function as line 40.&lt;/p&gt;

&lt;p&gt;Lines 26 to 36 provide an implementation to the GetEmployeeById method. We will ensure the id isn't null from the controller before sending it to this method so there is no need to check for null or empty values again here. After calling the employee property, we use the FindAsync(id) method to get the Employee with that id on line 28, then we return the Employee only if it exists.&lt;/p&gt;

&lt;p&gt;Lines 19 to 24 provide the implementation to the CreateEmployee method. The API Controller will validate the Employee object before passing it to this method so there is no need to validate the input here again. We use the AddAsync() method on line 21 to add the new Employee to the database but take note that the database won't be updated until we save the changes as shown on line 22.&lt;/p&gt;

&lt;p&gt;Lines 43 to 65 provide the implementation to the UpdateEmployee method. We check if the Employee exists in the database on line 45 before proceeding. Lines 49 to 57 are used to detach the entity before we update. The entity is being tracked due to line 45 hence, if we try updating it without detaching it first, we will get an error. We set the State of the Entity to Modified on line 59 hence notifying EntityFramewoke that the value(s) of that particular Employee has(have) been modified. We update the database and save the changes on lines 61 and 62.&lt;/p&gt;

&lt;p&gt;With this, we are done with the data access code. Now we will move to the Employee.API project to create our endpoints.&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating the Endpoints
&lt;/h2&gt;

&lt;p&gt;First, we need to perform some configurations. Replace the code in the &lt;strong&gt;Startup.cs&lt;/strong&gt; file with:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Lines 15, 38 to 42 and 54 are used to enable CORS on the endpoint. Line 36 is used to define the implementation of IEmployeeDAO interface that should be used during dependency injection which we specified as EmployeeDAO . &lt;br&gt;
Lines 34 and 35 define the database configuration that should be used. It looks for the connection string named EmployeeManagementDBContext (this name can be anything else) from either the appsettings.json file, secrets.json file or Environment variable. It searches for the parameter EmployeeManagementDBContext from either of those 3 locations. We will be making use of the appsettings.json to store it. Replace the code in the appsettings.json with:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Next, add a new empty API controller to the Controllers folder, name it &lt;strong&gt;EmployeeController.cs&lt;/strong&gt;. Replace the code in this file with:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We injected an instance of IEmployeeDAO through the constructor on lines 16 to 20. &lt;/p&gt;

&lt;p&gt;Lines 57 to 65 define the action method GetAll which responds to the request GET /Employee used to get all the Employees. &lt;/p&gt;

&lt;p&gt;Lines 41 to 54 define the action method GetById which responds to the request GET /Employee/{id} to get a particular Employee. &lt;/p&gt;

&lt;p&gt;Lines 23 to 38 define the action method Create which responds to the request POST /Employee to create a new Employee.&lt;/p&gt;

&lt;p&gt;Lines 68 to 79 define the action method Update which responds to the request PUT /Employee to update an Employee.&lt;/p&gt;

&lt;p&gt;For the delete functionality, in the IEmployeeDAO.cs file add another method that returns a &lt;strong&gt;Task&lt;/strong&gt; named &lt;strong&gt;DeleteEmployee&lt;/strong&gt; which takes in the id of the Employee to delete. Add the implementation of this method to the &lt;strong&gt;EmployeeDAO.cs&lt;/strong&gt;. &lt;br&gt;
First thing to do in this method is to get the Employee by calling the GetEmployeeById(id), then use the .Remove(employeeObjectTodelete) on the dbContext.employee property to delete the employee and then save the changes to the database.&lt;br&gt;
Next, in the &lt;strong&gt;EmployeeController.cs&lt;/strong&gt;, create an action method &lt;strong&gt;Delete&lt;/strong&gt; that takes in the id and marks it with the attribute [HttpDelete] then passes the id into the DeleteEmployee of IEmployeeDAO.cs and that is it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the Application
&lt;/h2&gt;

&lt;p&gt;Right-click the solution and click Build Solution. After Build is successful, click CTRL + f5 to run the application. If you have followed all the steps carefully, you shouldn't get any errors. Once the application starts running, you should get the image below in your browser:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fildtmn6m1otxulck1qrd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fildtmn6m1otxulck1qrd.jpg" alt="runmain" width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Isn't it amazing that Swagger docs are generated automatically for all our endpoints. We don't need Postman or other tools to test the endpoints again. We can do everything we need to do inside the browser now. &lt;br&gt;
Click the GET /api/Employee then click the &lt;strong&gt;Try it out&lt;/strong&gt; button and &lt;strong&gt;Execute&lt;/strong&gt;. You should get back the initial Employee we created earlier, alongside other Employees you created, if you did. &lt;br&gt;
Click the POST /api/Employee then &lt;strong&gt;Try it out&lt;/strong&gt;, you should get:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fw69n9blb6t4nup4p38bv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fw69n9blb6t4nup4p38bv.jpg" alt="runpost" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can edit the details of the id, name, department and email. If you remove the id field, the database will auto generate a unique id. If you pass in an invalid id, the record won't be stored instead, you will get an error message. If you pass in a valid id that already exists in the database, you will get an error message stating that. If you remove either of the name, department or email field and Execute it you will get back an error stating that the missing field is required due to the [Required] attribute used on them. If the value of the email isn't a valid email, you will get back a response saying  "The email field is not a valid e-mail address". If all went well, when you click the Execute button you should get back the newly created Employee.&lt;br&gt;
Try the PUT /api/Employee. For this, you will need to copy one of the Employees from the GET /api/Employee and update any of the values except the id then Execute it.&lt;br&gt;
Try out the GET /api/Employee/{id} too.&lt;/p&gt;

&lt;p&gt;Whoa! We have come to the end of this tutorial. This is not the end of your learning, there are still lots of things to learn e.g. Authentication, Authorization, MiddleWare etc. Those are advanced topics. Trust me when I say you are done with the basis. With the knowledge you just gained, you can develop a RESTful API that any mobile, web or desktop application can use.&lt;/p&gt;

&lt;p&gt;Awesome! Please share it with anyone you think could use this information. Thanks for reading. As always, if you have any questions, comments, or concerns about this post, feel free to leave a comment below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/dotnet/announcing-net-5-0/" rel="noopener noreferrer"&gt;You can get the complete list of .NET 5 features here.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>net5</category>
      <category>csharp</category>
      <category>cockroachdb</category>
    </item>
    <item>
      <title>Fun with ASP.NET Core Blazor WebAssembly and ML.NET</title>
      <dc:creator>John Ojo</dc:creator>
      <pubDate>Wed, 11 Nov 2020 16:11:49 +0000</pubDate>
      <link>https://dev.to/jioophoenix/fun-with-asp-net-core-blazor-webassembly-and-ml-net-4i29</link>
      <guid>https://dev.to/jioophoenix/fun-with-asp-net-core-blazor-webassembly-and-ml-net-4i29</guid>
      <description>&lt;h2&gt;
  
  
  What is Blazor WebAssembly?
&lt;/h2&gt;

&lt;p&gt;In case this is your first time learning about Blazor, let me introduce you to what Blazor WebAssembly is all about.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Blazor is an open source and cross-platform web UI framework for building single-page apps using .NET and C# instead of JavaScript. Blazor is based on a powerful and flexible component model for building rich interactive web UI. You implement Blazor UI components using a combination of .NET code and Razor syntax: an elegant melding of HTML and C#. Blazor components can seamlessly handle UI events, bind to user input, and efficiently render UI updates.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What is ML.NET?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;ML.NET is a free, cross-platform, open-source machine learning framework provided by Microsoft. It is made specifically for the .NET community. With the help of ML.Net framework, you can easily implement and integrate machine learning features into your existing or new .Net applications. &lt;br&gt;
To start working on ML.Net, you don’t have to be a machine learning expert. You can just start building simple ML.Net applications while teaching yourself.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this article, I am going to give a demo of a simple yet exciting ML.Net based project. We will develop an application that will be used to forecast bike rental service demand using univariate time series analysis.&lt;br&gt;
The code for this sample can be found on the &lt;a href="https://github.com/CloudBloq/BlazorWithML.NET" rel="noopener noreferrer"&gt;CloudBloq/BlazorWithML.NET&lt;/a&gt; repository on GitHub.&lt;/p&gt;
&lt;h2&gt;
  
  
  What You’ll Need to Get Started
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://visualstudio.microsoft.com/downloads/?utm_medium=microsoft&amp;amp;utm_source=docs.microsoft.com&amp;amp;utm_campaign=inline+link&amp;amp;utm_content=download+vs2019" rel="noopener noreferrer"&gt;Visual Studio 2019&lt;/a&gt; with the ".NET Core cross-platform development" workload installed.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Needed Projects
&lt;/h2&gt;

&lt;p&gt;We will be making use of three projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An ASP.NET Blazor WebAssembly project which serves as the UI to display the forecast.&lt;/li&gt;
&lt;li&gt;An ASP.NET Web Api project which feeds the UI with data (the bike rental service demand forecast) from the service.&lt;/li&gt;
&lt;li&gt;A service [C# Class Library (.NET Standard)] which will contain the logics used to forecast bike rental service demand.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you clone the &lt;a href="https://github.com/CloudBloq/BlazorWithML.NET" rel="noopener noreferrer"&gt;CloudBloq/BlazorWithML.NET&lt;/a&gt; repository, the database already resides in the Data folder in project BlazorWithML.NET.Api. When you run the application for the first time, the database will be automatically created and filled with the needed data. The database already contains the data that will be used to train the model.  &lt;/p&gt;
&lt;h2&gt;
  
  
  Setting Up the Projects
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ASP.NET Blazor WebAssembly project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Launch Visual Studio, click the &lt;strong&gt;Create a new project&lt;/strong&gt; link. Next, type &lt;strong&gt;Blazor&lt;/strong&gt; in the search box and click the first option that comes up (Blazor App):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frhb06im7tq65nopmmkao.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frhb06im7tq65nopmmkao.png" alt="image (1)" width="569" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Give the project and solution a name, e.g. &lt;strong&gt;BlazorWithML.NETPOC&lt;/strong&gt; then click the &lt;strong&gt;Create&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;Next, select the &lt;strong&gt;Blazor WebAssembly App&lt;/strong&gt; option and click the &lt;strong&gt;Create&lt;/strong&gt; button. This will create the project and solution for you. &lt;a href="https://medium.com/informatics/blazor-project-structure-e91a7c48ce1b" rel="noopener noreferrer"&gt;This link will help you understand a Blazor WebAssembly project structure&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ASP.NET Web Api project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Right click the Solution in the Solution Explorer and select Add -&amp;gt; New Project, search for &lt;strong&gt;Web Application&lt;/strong&gt; and select the &lt;strong&gt;ASP.NET Core Web Application&lt;/strong&gt; option:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ne84l78tbj2thpnbw90.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ne84l78tbj2thpnbw90.jpg" alt="webap" width="555" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;click &lt;strong&gt;Next&lt;/strong&gt;, give the project a name &lt;strong&gt;BlazorWithML.NET.Api&lt;/strong&gt;, then click &lt;strong&gt;Create&lt;/strong&gt;, select the &lt;strong&gt;API&lt;/strong&gt; option:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgjwti8e67tkml1cjxb1b.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgjwti8e67tkml1cjxb1b.jpg" alt="api" width="686" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and finally click &lt;strong&gt;Create&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;C# Class Library (.NET Standard)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Right click the Solution in the Solution Explorer and select Add -&amp;gt; New Project, search for &lt;strong&gt;Class Library (.NET Standard)&lt;/strong&gt; and select the C# version. Click &lt;strong&gt;Next&lt;/strong&gt;, give the project a name &lt;strong&gt;Forecasting_BikeSharingDemandLib&lt;/strong&gt;, then click &lt;strong&gt;Create&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Adding Projects Dependencies
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We need to add the ML.NET and SqlClient package to the service: Right-click the Forecasting_BikeSharingDemandLib project, select &lt;strong&gt;Manage NuGet Packages for Solution&lt;/strong&gt;. Under the Browse section, search for &lt;strong&gt;Microsoft.ML&lt;/strong&gt; and click on it then click the Install button. After that, search for &lt;strong&gt;Microsoft.ML.Timeseries&lt;/strong&gt; then click the Install button. Also search for &lt;strong&gt;System.Data.SqlClient&lt;/strong&gt; and Install it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We need to give the Api access to the Service: This can be done by adding a reference of the service to the Api. Right-click the Dependencies of project BlazorWithML.NET.Api and click Add project Reference, select the Forecasting_BikeSharingDemandLib checkbox and click ok.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Writing the Service
&lt;/h2&gt;

&lt;p&gt;The service is the backend of the application. It contains the logics used to forecast bike rental service demand. &lt;br&gt;
We will make use of univariate time series analysis algorithm known as &lt;a href="http://ssa.cf.ac.uk/zhigljavsky/pdfs/SSA/SSA_encyclopedia.pdf" rel="noopener noreferrer"&gt;Singular Spectrum Analysis&lt;/a&gt; to forecast the demand for bike rentals.&lt;/p&gt;
&lt;h3&gt;
  
  
  Understand the problem
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;In order to run an efficient operation, inventory management plays a key role. Having too much of a product in stock means not generating any revenue. Having too little product leads to lost sales. Therefore, the constant question is, what is the optimal amount of inventory to keep on hand? Time-series analysis helps provide an answer to these questions by looking at historical data, identifying patterns, and using this information to forecast values some time in the future.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The algorithm used in this article for analyzing data is univariate time-series analysis. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Univariate time-series analysis takes a look at a single numerical observation over a period of time at specific intervals, for example monthly sales. It works by decomposing a time-series into a set of principal components. These components can be interpreted as the parts of a signal that correspond to trends, noise, seasonality, and many other factors. Then, these components are reconstructed and used to forecast values some time in the future.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Create the needed files and folders
&lt;/h3&gt;

&lt;p&gt;Right-click the Forecasting_BikeSharingDemandLib in the Solution Explorer then select Add -&amp;gt; New Folder and give it the name &lt;strong&gt;Model&lt;/strong&gt;. This folder will contain the objects used to model the output. &lt;/p&gt;

&lt;p&gt;The output will be in two forms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Evaluation, which will contain the &lt;strong&gt;Mean Absolute Error&lt;/strong&gt; and the &lt;strong&gt;Root Mean Squared Error&lt;/strong&gt; and&lt;/li&gt;
&lt;li&gt;The Forecast, which will contain &lt;strong&gt;Lower Estimate&lt;/strong&gt;, &lt;strong&gt;UpperEstimate&lt;/strong&gt;, &lt;strong&gt;Forecast&lt;/strong&gt;...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create the Forecast output object by right clicking the Model folder and select Add -&amp;gt; class then name it &lt;strong&gt;ForecastOutput.cs&lt;/strong&gt;. The code for it is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ForecastOutput&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Date&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;ActualRentals&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;LowerEstimate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;Forecast&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;UpperEstimate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Next, right-click the Model folder and select Add -&amp;gt; class then name it &lt;strong&gt;EvaluateOutput.cs&lt;/strong&gt;. The code for it is:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EvaluateOutput&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;MeanAbsoluteError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;RootMeanSquaredError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We also need to add the class that will contain the logic. Right-click the project Forecasting_BikeSharingDemandLib and select Add -&amp;gt; class then name it &lt;strong&gt;BikeForcast.cs&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Logic
&lt;/h3&gt;

&lt;p&gt;The entire code for the file &lt;strong&gt;BikeForcast.cs&lt;/strong&gt; is (I will break it down bit by bit): &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;GetConnectionString(), lines 15 to 22, is used to get the connection string where the data is stored and also the Model path. MLModel.zip can be found in the root folder of project BlazorWithML.NET.Api. &lt;/p&gt;

&lt;p&gt;Lines 144 to 151 define the ModelInput class. This class is used to hold the database objects and it contains the following columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RentalDate&lt;/strong&gt;: The date of the observation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Year&lt;/strong&gt;: The encoded year of the observation (0=2011, 1=2012).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TotalRentals&lt;/strong&gt;: The total number of bike rentals for that day.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lines 153 to 161 define the ModelOutput class. This class contains the following columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ForecastedRentals&lt;/strong&gt;: The predicted values for the forecasted period.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LowerBoundRentals&lt;/strong&gt;: The predicted minimum values for the forecasted period.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UpperBoundRentals&lt;/strong&gt;: The predicted maximum values for the forecasted period.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Line 24 defines the GetBikeForcast() method that takes in a parameter numberOfDaysToPredict : int. The parameter will be gotten from the UI. The user will have to input the amount of days (between 1 and 500) he/she wants to predict for. This method holds the logic to forecast the demands with the help of two other methods for Evaluate and Forecast.&lt;/p&gt;

&lt;p&gt;Line 26 defines the MLContext. The &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.ml.mlcontext" rel="noopener noreferrer"&gt;MLContext&lt;/a&gt; class is a starting point for all ML.NET operations, and initializing mlContext creates a new ML.NET environment that can be shared across the model creation workflow objects. It's similar, conceptually, to DBContext in Entity Framework.&lt;/p&gt;

&lt;p&gt;Next we need to load the data from the database. &lt;br&gt;
Line 29 creates a DatabaseLoader that loads records of type ModelInput. Line 32 defines the query to load the data from the database. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ML.NET algorithms expect data to be of type Single. Therefore, numerical values coming from the database that are not of type Real, a single-precision floating-point value, have to be converted to Real.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Year and TotalRental columns are both integer types in the database. Using the CAST built-in function, they are both cast to Real.&lt;br&gt;
We will create a DatabaseSource to connect to the database and execute the query on line 35, after which we then load the data into an IDataView on line 40.&lt;/p&gt;

&lt;p&gt;The dataset contains two years' worth of data. Only data from the first year is used for training; the second year's data is held out to compare the actual values against the forecast produced by the model. Filter the data (line 43 and 44) using the FilterRowsByColumn transform. &lt;br&gt;
For the first year, only the values in the Year column less than 1 are selected by setting the upperBound parameter to 1. Conversely, for the second year, values greater than or equal to 1 are selected by setting the lowerBound parameter to 1.&lt;/p&gt;

&lt;p&gt;Next, we will define a pipeline that uses the &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.ml.transforms.timeseries.ssaforecastingestimator" rel="noopener noreferrer"&gt;SsaForecastingEstimator&lt;/a&gt; to forecast values in a time-series dataset, as shown on lines 47 to 56. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The forecastingPipeline takes 365 data points for the first year and samples or splits the time-series dataset into 30-day (monthly) intervals as specified by the seriesLength parameter. Each of these samples is analyzed through a weekly or 7-day window. When determining what the forecasted value for the next period(s) is(are), the values from the previous seven days are used to make a prediction. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The model is set to forecast a period of the number of day(s) the User input into the future as defined by the horizon parameter. Because a forecast is an informed guess, it's not always 100% accurate. Therefore, it's good to know the range of values in the best and worst-case scenarios as defined by the upper and lower bounds. In this case, the level of confidence for the lower and upper bounds is set to 95%. The confidence level can be increased or decreased accordingly. The higher the value, the wider the range is between the upper and lower bounds to achieve the desired level of confidence.&lt;br&gt;
On line 59, we use the Fit method to train the model and fit the data to the previously defined forecastingPipeline.&lt;/p&gt;

&lt;p&gt;Next, we will evaluate the model, and lines 74 to 104 defines an helper method that will be used to evaluate the model.&lt;br&gt;
To evaluate performance, the following metrics are used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mean Absolute Error&lt;/strong&gt;: Measures how close predictions are to the actual value. This value ranges between 0 and infinity. The closer to 0, the better the quality of the model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Root Mean Squared Error&lt;/strong&gt;: Summarizes the error in the model. This value ranges between 0 and infinity. The closer to 0, the better the quality of the model.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We evaluate how well the model performs by forecasting next year's data and comparing it against the actual values. &lt;br&gt;
Inside the Evaluate method, forecast the second year's data by using the Transform method with the trained model on line 77.&lt;br&gt;
We get the actual values from the data by using the CreateEnumerable method on line 80, and the forecasted values by using the CreateEnumerable method on line 85.&lt;br&gt;
We then calculate the difference between the actual and forecasted values, commonly referred to as the error, on line 90.&lt;br&gt;
We measure performance by computing the Mean Absolute Error and Root Mean Squared Error values on lines 93 and 94.&lt;/p&gt;

&lt;p&gt;Next, we need to save the evaluated model. The model is saved in a file called MLModel.zip as specified by the previously defined modelPath variable from the GetConnectionString() method. Use the Checkpoint method to save the model on line 66.  &lt;/p&gt;

&lt;p&gt;Finally, we will use the model to forecast demand. Lines 106 to 140 define the Forecast helper method. &lt;br&gt;
We create a List to hold the result of the forecast on line 108, then we use the Predict method on line 111 to forecast rentals for the number of day(s) entered by the user.&lt;br&gt;
Then we align the actual and forecasted values on lines 113 to 131.&lt;/p&gt;

&lt;p&gt;With this, we are done with the logic.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Api
&lt;/h2&gt;

&lt;p&gt;The Blazor WebAssembly app will need an Api to get the forecast from the service. First, we need to enable &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" rel="noopener noreferrer"&gt;CORS&lt;/a&gt; on the Api. Go to the Startup.cs file of project BlazorWithML.NET.Api. Create a new field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;AllowedOrigin&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"allowedOrigin"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Next, add the CORS service to your app by adding these lines of code to the ConfigureServices(IServiceCollection services) method:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddCors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"allowedOrigin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AllowAnyOrigin&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;AllowAnyMethod&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;AllowAnyHeader&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Finally, add the CORS middleware to the Configure(IApplicationBuilder app, IWebHostEnvironment env) method:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseCors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AllowedOrigin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ensure that this middleware is added as the first middleware in the pipeline that is right after the:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsDevelopment&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseDeveloperExceptionPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  The Controller
&lt;/h3&gt;

&lt;p&gt;Create an empty Api controller in the Controllers folder, and name it &lt;strong&gt;BikeDemandForcastController.cs&lt;/strong&gt;. The code for this controller is:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The first endpoint, lines 11 to 17, (/GetEvaluateOutput/{numberOfDaysToPredict}) is used to get the EvaluateOutput.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The second endpoint, lines 20 to 26, (/GetForecastOutput/{numberOfDaysToPredict}) is used to get the ForecastOutput. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The UI
&lt;/h2&gt;

&lt;p&gt;First, we are going to set the base Uri of the Api endpoints. This can be done in the Program.cs of project BlazorWithML.NET by replacing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddScoped&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sp&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;HttpClient&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;BaseAddress&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HostEnvironment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseAddress&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;with&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddScoped&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sp&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;HttpClient&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;BaseAddress&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://localhost:5001/api/"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Model Objects
&lt;/h3&gt;

&lt;p&gt;The Api returns data in JSON format so we need to map the response data to an object which would be displayed to the user. Create a new folder called Model and create a class called ForecastOutput.cs in the Model folder. The code for this class is:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Create another class called EvaluateOutput.cs:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We will also need an object to store the input from the user. In the Model folder create a class called BikeForcastInput.cs:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Blazor Page
&lt;/h3&gt;

&lt;p&gt;Blazor pages end with .razor and they are called Razor component. &lt;br&gt;
In the Pages folder, create a Razor Component and name it BikeForcast.razor This component will be used to get the input(number of day(s) from the user) and display the Evaluate and Forecast output. The code is:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Line 1 defines the Uri the BikeForcast.razor will be mapped to. Lines 11 to 70 define the components that will be displayed to the user. The GetBikeDemandForcast() (lines 78 to 82) is used to call the endpoints to get the Evaluate and Forecast. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Replace the code in the NavMenu.razor component in the Shared folder with:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;With this, we are done with coding. Now it's time to test our application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing the application
&lt;/h2&gt;

&lt;p&gt;First, we need to set the UI (BlazorWithML.NET) and Api (BlazorWithML.NET.Api) to start up at the same time when we run the application. &lt;br&gt;
Right-click the solution then click &lt;strong&gt;Set Startup Projects&lt;/strong&gt;. Select &lt;strong&gt;Multiple startup projects&lt;/strong&gt; and set the Action of BlazorWithML.NET and BlazorWithML.NET.Api to Start. You should get the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxybdbwk24b5s0c1y7ncb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxybdbwk24b5s0c1y7ncb.jpg" alt="start" width="800" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click Apply then Ok. Right-click the solution and click Build Solution. After Build is successful, click CTRL + f5 to run the application. If you are getting an IIS error restart your VS Build the project again, and click CTRL + f5. Once the application is running you, should get the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F56r8qujl16te6yq11xym.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F56r8qujl16te6yq11xym.jpg" alt="blazor1" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;Bike Demand Forcast&lt;/strong&gt; link, enter a number between 1 and 500, and you should get the result of the Forecast in a table as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp17mvxy76aqkcl2ofi53.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp17mvxy76aqkcl2ofi53.jpg" alt="bla2" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Do More Blazor or ML.NET!!
&lt;/h2&gt;

&lt;p&gt;If you enjoyed this article and feel like learning more about Blazor WebAssembly or ML.NET, the links below might be just what you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/aspnet/core/tutorials/signalr-blazor-webassembly?view=aspnetcore-3.1&amp;amp;tabs=visual-studio" rel="noopener noreferrer"&gt;Use ASP.NET Core SignalR with Blazor WebAssembly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jeremylikness.com/blog/advanced-blazor-shared-assemblies-debugging/" rel="noopener noreferrer"&gt;Advanced Blazor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-gb/dotnet/machine-learning/" rel="noopener noreferrer"&gt;ML.NET Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Awesome! Please share it with anyone you think could use this information. Thanks for reading. As always if you have any questions, comments, or concerns about this post feel free to leave a comment below. &lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>blazor</category>
      <category>mlnet</category>
      <category>netcore</category>
    </item>
    <item>
      <title>Develop a Simple CRUD App with ASP.NET Core Blazor WebAssembly and CockroachDB</title>
      <dc:creator>John Ojo</dc:creator>
      <pubDate>Tue, 13 Oct 2020 15:09:52 +0000</pubDate>
      <link>https://dev.to/jioophoenix/develop-a-simple-crud-app-with-asp-net-core-blazor-webassembly-and-cockroachdb-4d1a</link>
      <guid>https://dev.to/jioophoenix/develop-a-simple-crud-app-with-asp-net-core-blazor-webassembly-and-cockroachdb-4d1a</guid>
      <description>&lt;p&gt;In this post, I will walk you through how to get started with ASP.NET Core Blazor WebAssembly app by developing an app that performs basic CRUD. We will be making use of CockroachDB as the database, &lt;a href="https://docs.microsoft.com/en-us/ef/core/get-started/?tabs=netcore-cli" rel="noopener noreferrer"&gt;Entity Framework Core&lt;/a&gt; as the ORM.&lt;/p&gt;

&lt;p&gt;The basic CRUD app will be a bank account with just &lt;em&gt;name&lt;/em&gt; and &lt;em&gt;balance&lt;/em&gt; where we can &lt;strong&gt;C&lt;/strong&gt;reate, &lt;strong&gt;R&lt;/strong&gt;ead, &lt;strong&gt;U&lt;/strong&gt;pdate, and &lt;strong&gt;D&lt;/strong&gt;elete accounts. &lt;/p&gt;

&lt;p&gt;The source code on GitHub : &lt;a href="https://github.com/CloudBloq/BlazorAppWithCockroachDB" rel="noopener noreferrer"&gt;BlazorAppWithCockroachDB&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://visualstudio.microsoft.com/vs/" rel="noopener noreferrer"&gt;Visual Studio 2019 (version 16.5 upwards)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cockroachlabs.com/docs/stable/install-cockroachdb-windows.html" rel="noopener noreferrer"&gt;CockroachDB&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Blazor is an open source and cross-platform web UI framework for building single-page apps using .NET and C# instead of JavaScript. Blazor is based on a powerful and flexible component model for building rich interactive web UI. You implement Blazor UI components using a combination of .NET code and Razor syntax: an elegant melding of HTML and C#.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Pcyx48AgR40"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Cockroach Labs is the company behind CockroachDB, the cloud-native, distributed SQL database that provides next-level consistency, ultra-resilience, data locality, and massive scale to modern cloud applications.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ZAzgd4xvV7o"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Create the Solution and Projects
&lt;/h2&gt;

&lt;p&gt;We will be making use of three projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;BlazorAppWithCockroachDB- A Blazor WebAssembly project.
After opening VS, click the &lt;strong&gt;Create a new project&lt;/strong&gt; link. Next type &lt;strong&gt;Blazor&lt;/strong&gt; in the search box and choose the first option that comes up (Blazor App):&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frhb06im7tq65nopmmkao.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frhb06im7tq65nopmmkao.png" alt="image (1)" width="569" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Give the project and solution a name e.g. &lt;strong&gt;BlazorAppWithCockroachDB&lt;/strong&gt; then click the &lt;strong&gt;Create&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;Next select the &lt;strong&gt;Blazor WebAssembly App&lt;/strong&gt; option and click the &lt;strong&gt;Create&lt;/strong&gt; button this will create the project and solution for you. &lt;a href="https://medium.com/informatics/blazor-project-structure-e91a7c48ce1b" rel="noopener noreferrer"&gt;This link will help you understand a Blazor WebAssembly project structure&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;BlazorAppWithCockroachDB.Api- A Web API project, which is used to get data across to the Blazor app.
Right click the Solution in the Solution Explorer and select Add -&amp;gt; New Project, search for &lt;strong&gt;Web Application&lt;/strong&gt; and select the &lt;strong&gt;ASP.NET Core Web Application&lt;/strong&gt; option:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ne84l78tbj2thpnbw90.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ne84l78tbj2thpnbw90.jpg" alt="webap" width="555" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;click &lt;strong&gt;Next&lt;/strong&gt;, give the project a name BlazorAppWithCockroachDB.Api, then click &lt;strong&gt;Create&lt;/strong&gt;, select the &lt;strong&gt;API&lt;/strong&gt; option:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgjwti8e67tkml1cjxb1b.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgjwti8e67tkml1cjxb1b.jpg" alt="api" width="686" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and finally click &lt;strong&gt;Create&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CockroachDbLib- A class Library which holds the database objects and data access codes.
Right click the Solution in the Solution Explorer and select Add -&amp;gt; New Project, search for &lt;strong&gt;Class Library&lt;/strong&gt; then select the &lt;strong&gt;Class Library (.NET Standard)&lt;/strong&gt; option click &lt;strong&gt;Next&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvp8pbv78f1ofsu0n6y2e.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvp8pbv78f1ofsu0n6y2e.jpg" alt="lib" width="555" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next give the library a name e.g. &lt;strong&gt;CockroachDbLib&lt;/strong&gt; and click &lt;strong&gt;Create&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Dependencies
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;We need to install the &lt;a href="http://www.npgsql.org/efcore/index.html" rel="noopener noreferrer"&gt;&lt;strong&gt;Npgsql.EntityFrameworkCore.PostgreSQL&lt;/strong&gt;&lt;/a&gt; package. This package will be used to communicate with the database. To install the package, right click the solution in the solution explorer and select &lt;strong&gt;Manage NuGet Packages for Solution&lt;/strong&gt;. Under the &lt;strong&gt;Browse&lt;/strong&gt; section, search for &lt;strong&gt;Npgsql.EntityFrameworkCore.PostgreSQL&lt;/strong&gt; and click on it, then in the preview panel, select the BlazorAppWithCockroachDB.Api and CockroachDbLib checkbox so it will be installed only into the projects BlazorAppWithCockroachDB.Api and CockroachDbLib and click the &lt;strong&gt;Install&lt;/strong&gt; button:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fi5ifqyxkccd7k96mr7bd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fi5ifqyxkccd7k96mr7bd.jpg" alt="nuget1" width="800" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We need &lt;a href="https://www.newtonsoft.com/json" rel="noopener noreferrer"&gt;Newtonsoft.Json&lt;/a&gt; to Serialize and Deserialize the API response. Search for Newtonsoft.Json under the browse section and click it and in the preview section, select only the BlazorAppWithCockroachDB checkbox and click the &lt;strong&gt;Install&lt;/strong&gt; button:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3e2ii0zz7v9v6qxkv29q.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3e2ii0zz7v9v6qxkv29q.jpg" alt="nn" width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Finally, we need to add a reference for project CockroachDbLib to BlazorAppWithCockroachDB.Api. To do this, right click the Dependencies and click Add project Reference, select the CockroachDbLib checkbox and click ok:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0pyw26e7ted6oyn34lmf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0pyw26e7ted6oyn34lmf.jpg" alt="dd" width="264" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjafz9ml5gh880ronef97.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjafz9ml5gh880ronef97.jpg" alt="chc" width="782" height="541"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Database
&lt;/h2&gt;

&lt;p&gt;After &lt;a href="https://www.cockroachlabs.com/docs/v20.1/start-a-local-cluster" rel="noopener noreferrer"&gt;starting a cluster in insecure mode&lt;/a&gt; (&lt;a href="https://www.cockroachlabs.com/docs/v20.1/start-a-local-cluster-in-docker-windows" rel="noopener noreferrer"&gt;this is for the Docker version&lt;/a&gt;), we need to &lt;a href="https://www.cockroachlabs.com/docs/v20.1/cockroach-sql.html#start-a-sql-shell" rel="noopener noreferrer"&gt;connect a SQL shell to the cluster in insecure mode&lt;/a&gt;. In the SQL Shell create a database (bank) and a table (accounts) with columns id:int, name:string and balance:int. The query is given below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;bank&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;bank&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;accounts&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Add initial data to the database:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;bank&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;accounts&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'John'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;bank&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;accounts&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Eric'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;750&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Check the data by running:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;bank&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Defining the Database Entity
&lt;/h2&gt;

&lt;p&gt;Database objects (tables) are defined as Entities using Entity Framework Core. The database object, in this case, the &lt;strong&gt;accounts&lt;/strong&gt; table will be represented as an entity (a C# class file). The naming of the class doesn't really matter here, when hooking up the class/entity in the &lt;a href="https://www.entityframeworktutorial.net/efcore/entity-framework-core-dbcontext.aspx" rel="noopener noreferrer"&gt;DbContext&lt;/a&gt;, the name given to the variable/property used to link the entity to the DbContext must match exactly with the name of the table in the database.&lt;/p&gt;

&lt;p&gt;Create a folder called &lt;strong&gt;Models&lt;/strong&gt; in the &lt;strong&gt;CockroachDbLib&lt;/strong&gt; project, and in that folder add a new class file called Account.cs. The code is:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Each column is mapped to a property as shown in the figure above. The name and data type of the property must match exactly with that of the column in the database table. &lt;/p&gt;

&lt;h2&gt;
  
  
  Defining the DbContext
&lt;/h2&gt;

&lt;p&gt;Create a new class file CockroachDbContext.cs also in the Models folder. The code for the file:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Line 14: is used to link the Entity to the Dbcontext hence to the database table &lt;strong&gt;accounts&lt;/strong&gt;: if the property name doesn't match the table name exactly, an error will occur.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Repository
&lt;/h2&gt;

&lt;p&gt;This is where all the data access code will be written. We will be making use of dependency injection (using interface) when calling the access code.&lt;br&gt;
Create a new folder &lt;strong&gt;Repository&lt;/strong&gt; in the &lt;strong&gt;CockroachDbLib&lt;/strong&gt; project and in this folder add a new Interface file called &lt;strong&gt;IAccountRepository.cs&lt;/strong&gt; The code for the file:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This interface defines all the methods needed to perform the CRUD.&lt;/p&gt;

&lt;p&gt;Finally, create the &lt;strong&gt;AccountRepository.cs&lt;/strong&gt; class file in the Repository folder also. This class implements the IAccountRepository.cs hence providing implementations to the methods defined in the interface:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;With this, we are done with the CockroachDbLib.cs project&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the API Endpoints
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Adding Configuration
&lt;/h3&gt;

&lt;p&gt;The BlazorAppWithCockroachDB.Api project will be used to create all the required endpoints to get and store data.&lt;/p&gt;

&lt;p&gt;We need to add some configurations. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First we need to enable &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" rel="noopener noreferrer"&gt;&lt;strong&gt;CORS&lt;/strong&gt;&lt;/a&gt; on the API which can be done easily in the &lt;strong&gt;Startup.cs&lt;/strong&gt; file.
Create a new field in the Startup.cs file:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;AllowedOrigin&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"allowedOrigin"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Next, add the CORS service to your app by adding these lines of code to the ConfigureServices(IServiceCollection services) method:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddCors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"allowedOrigin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AllowAnyOrigin&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;AllowAnyMethod&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;AllowAnyHeader&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Finally, add the CORS middleware to the Configure(IApplicationBuilder app, IWebHostEnvironment env) method:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseCors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AllowedOrigin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ensure that this middleware is added as the first middleware in the pipeline that is right after the:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsDevelopment&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseDeveloperExceptionPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;The next is to configure the DbContext which can be done by adding this line of code in the ConfigureServices(IServiceCollection services) method of the Startup.cs file:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CockroachDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
                &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseNpgsql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetConnectionString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CockroachDb"&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This line requires the ConnectionString which will be added to the appsettings.json file as:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;"ConnectionStrings": {
    "CockroachDb": "Host=localhost;Database=bank;Username=John;Port=26257"
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The Username should be the user you created and assigned to the database from the SQL shell or omitted if you didn't add any user. The Port must be the port number you used to start up the local cluster for CockroachDb. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The last step is to inject the IAccountRepository dependency which can be done by adding:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddTransient&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IAccountRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AccountRepository&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;in the ConfigureServices(IServiceCollection services) method of the Startup.cs file.&lt;br&gt;
Ensure to import all the required namespace in case you are getting an error with the added lines.&lt;/p&gt;
&lt;h3&gt;
  
  
  Defining the Endpoints
&lt;/h3&gt;

&lt;p&gt;Create a new API Controller in the &lt;strong&gt;Controllers&lt;/strong&gt; folder of project BlazorAppWithCockroachDB.Api and name it AccountController.cs. This controller is going to contain all the endpoints we need. The code for the AccountController.cs file:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;The list of endpoints we have from the AccountController.cs are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://localhost:44368/api/Account/GetAll" rel="noopener noreferrer"&gt;https://localhost:44368/api/Account/GetAll&lt;/a&gt; - to return a List containing all the Accounts in the bank&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://localhost:44368/api/Account/Get/%7Bid%7D" rel="noopener noreferrer"&gt;https://localhost:44368/api/Account/Get/{id}&lt;/a&gt; - to get an Account by the id.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://localhost:44368/api/Account/GetLastAccountId" rel="noopener noreferrer"&gt;https://localhost:44368/api/Account/GetLastAccountId&lt;/a&gt; - to get the id of the last Account.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://localhost:44368/api/Account/Create" rel="noopener noreferrer"&gt;https://localhost:44368/api/Account/Create&lt;/a&gt; - to create a new Account &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://localhost:44368/api/Account/Update" rel="noopener noreferrer"&gt;https://localhost:44368/api/Account/Update&lt;/a&gt; - to update the details of an account.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://localhost:44368/api/Account/Delete/%7Bid%7D" rel="noopener noreferrer"&gt;https://localhost:44368/api/Account/Delete/{id}&lt;/a&gt; - to delete an account.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The 44368 will be replaced with the port VS uses for yours, this can be gotten from the launchSettings.json file in the &lt;strong&gt;Properties&lt;/strong&gt; folder.&lt;/p&gt;

&lt;p&gt;Now that the API is ready it's time to move to the last part which is the Blazor App (project BlazorAppWithCockroachDB).&lt;/p&gt;

&lt;h2&gt;
  
  
  Blazor App
&lt;/h2&gt;

&lt;p&gt;The first thing to do is to set the base Uri of the API endpoints. This can be done in the Program.cs file by replacing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddScoped&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sp&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;HttpClient&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;BaseAddress&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HostEnvironment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseAddress&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;with&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddScoped&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sp&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;HttpClient&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;BaseAddress&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://localhost:44368/api/"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Model Objects
&lt;/h3&gt;

&lt;p&gt;The API returns data in JSON format so we would need to map the response data to an object which would be displayed to the user. Create a new folder called Model. &lt;br&gt;
Create a class called Account.cs; this will be similar to the Account.cs in the CockroachDbLib.Models namespace. The code for the new Account.cs is:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;The second Model object will be used when the user wants to create or edit an account. Create another class file AccountModel.cs in the Model folder. The code for this file is:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Blazor Pages
&lt;/h3&gt;

&lt;p&gt;Blazor pages ends with .razor and they are called Razor component.&lt;br&gt;
Create a new folder called Bank and in this folder create a Razor Component and name it Accounts.razor This component will be used to display all the Accounts and also contain other links to other components. The code is:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The accounts are displayed in a tabular form - line 17 to 35. The DeleteAccount function  - line 50 to 75 defines the process called when the Delete button is clicked against an account - line 31.&lt;br&gt;
Line 47 calls the /GetaAll endpoint and line 55 calls the /Delete/{id} passing the id of the account selected.&lt;/p&gt;

&lt;p&gt;Next create another Razor component CreateAccount.razor in the Bank folder. This component will be used to add a new account. The code for this component:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Line 39 to 64 contains the code to add a new account. Notice I got the last account's id, added 1 to it and used it as the new id of the new account; you might not want to do this in a real application. A better alternative is to create the id as a Guid type and create a new Guid for every account.&lt;/p&gt;

&lt;p&gt;Next, we need the component to edit an account. Add a new Razor component called EditAccount.razor. The code for this is:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Finally, we need a component to view the details of an account. Add a Razor component called SingleAccount.razor. The code is:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Navigation
&lt;/h3&gt;

&lt;p&gt;Replace the code in the NavMenu.razor component in the Shared folder with:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Testing the application
&lt;/h2&gt;

&lt;p&gt;At this point, we are done with coding. Save all the changes made to the files, build project, make sure there is no error in any file. &lt;br&gt;
Run the BlazorAppWithCockroachDB.Api project first and test one of the endpoints using your browser or Postman, then run the BlazorAppWithCockroachDB project. You should get the:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6i3ozcfoxsykuckldv8i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6i3ozcfoxsykuckldv8i.png" alt="image (1)" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you click the All Account nav link you should get all the accounts we created earlier:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe835rfqwusodoy2toqgz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe835rfqwusodoy2toqgz.png" alt="image (1)" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Try creating, editing or deleting an account to make sure all the functions are working fine.&lt;/p&gt;

&lt;p&gt;Awesome! Please share it with anyone you think could use this information. Thanks for reading. &lt;/p&gt;

&lt;p&gt;Below are some links to keep you going if you are really interested in Blazor WebAssembly or CockroachDb:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/aspnet/core/tutorials/signalr-blazor-webassembly?view=aspnetcore-3.1&amp;amp;tabs=visual-studio" rel="noopener noreferrer"&gt;Use ASP.NET Core SignalR with Blazor WebAssembly&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="//cockroachlabs.com/docs/stable/learn-cockroachdb-sql.html"&gt;Learn CockroachDB SQL&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>blazor</category>
      <category>cockroachdb</category>
    </item>
  </channel>
</rss>
