<?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: Hui`s Journal of Technology</title>
    <description>The latest articles on DEV Community by Hui`s Journal of Technology (@huihzhao).</description>
    <link>https://dev.to/huihzhao</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%2F822776%2Ff53f3a94-6e27-4db3-a285-6228e465f92f.png</url>
      <title>DEV Community: Hui`s Journal of Technology</title>
      <link>https://dev.to/huihzhao</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/huihzhao"/>
    <language>en</language>
    <item>
      <title>Developer tools matter!</title>
      <dc:creator>Hui`s Journal of Technology</dc:creator>
      <pubDate>Mon, 28 Mar 2022 02:46:59 +0000</pubDate>
      <link>https://dev.to/huihzhao/developer-tools-matter-5868</link>
      <guid>https://dev.to/huihzhao/developer-tools-matter-5868</guid>
      <description>&lt;p&gt;May you think developer tools are only relevant to the personal behaviors of developers. From my prior experiences, developer tools may impact the teams collaboration, reliability of applications and even business outcome. &lt;br&gt;
In this article, I will talk about why developer tools matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mind pattern of a team
&lt;/h2&gt;

&lt;p&gt;A shared mind pattern of a team is the lubricant of smooth communication.  If a team can form an agreement on a code boilerplate generator, developers of the team can foster a shared mind set of how their code will be structured. Standardization of engineering practices is your friend if you want to scale your development team quickly when your business expands. When I started my project, my team and I only focuses on the features delivery to meet business requirements, and we only had 6 team members, and each of us has an our own set of tools and development habits. In the name of polyglot of Microservices, some of services are constructed in varied ways. As our business grows, the code maintenance workload becomes overwhelming and new features delivery were dragged behind because developers have to spend hours to understand services that are developed by his/her peers. Besides the learning cost, when we try to build the CI/CD pipelines, because of varied code structure, multiple pipelines are needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Service reliability
&lt;/h2&gt;

&lt;p&gt;Service reliability are often ignored at the beginning. You must often hear saying of "Let's focus on the features first and fix the reliability issue when business is impacted". By saying this, reliability of services are often ignored until something really bad happens. Reliability must be considered at the beginning. Developer tools often have the reliability features included, that means we can use the tool to have the service built in the correct way so that the reliability features are included inherently. &lt;/p&gt;

&lt;h2&gt;
  
  
  Service security
&lt;/h2&gt;

&lt;p&gt;Security and reliability are often interconnected. A shared framework and development toolset can enable the authentication, authorization, encryption, key management, and etc inherently. By doing this, the security review are much more efficient. Developers can focus on what really matters to the business logic.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>devops</category>
      <category>discuss</category>
    </item>
    <item>
      <title>A schema first development toolkit for protobuf</title>
      <dc:creator>Hui`s Journal of Technology</dc:creator>
      <pubDate>Fri, 25 Mar 2022 03:27:06 +0000</pubDate>
      <link>https://dev.to/huihzhao/a-schema-first-development-toolkit-for-protobuf-2mof</link>
      <guid>https://dev.to/huihzhao/a-schema-first-development-toolkit-for-protobuf-2mof</guid>
      <description>&lt;p&gt;I am recently working on a project called skemaloop, which is a schema-first or schema driven development toolkit that can help you start your API journey. &lt;/p&gt;

&lt;p&gt;You can find it here. &lt;br&gt;
&lt;a href="https://skemaloop.dev"&gt;https://skemaloop.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is a project that is still in early stage, and I will keep writing articles to introduce the functions of this toolkit and collect feedback from the dev community. &lt;/p&gt;

</description>
      <category>api</category>
      <category>protobuf</category>
      <category>grpc</category>
      <category>go</category>
    </item>
    <item>
      <title>why IDL matters in API development</title>
      <dc:creator>Hui`s Journal of Technology</dc:creator>
      <pubDate>Fri, 25 Mar 2022 03:22:07 +0000</pubDate>
      <link>https://dev.to/huihzhao/why-idl-matters-in-api-development-4ng3</link>
      <guid>https://dev.to/huihzhao/why-idl-matters-in-api-development-4ng3</guid>
      <description>&lt;p&gt;We are in the era of API, and our services are exposed in APIs. When there is a new business requirement coming, a context storming happens and the feature will be degined in the principle of DDD and implemented in the form of APIs. A backend developer starts his work by designing an API contract and share it with his/her frontend peers. Frontend developers or from other team design their functions by the API contract. That is to say, we must work on a solid foundation of API contract so that everyone who are in the scope can work independently and start their work in parallel.&lt;/p&gt;

&lt;p&gt;This document talks about the the problem of API contact sharing that we face everyday, and why it is neccessary to reconsider how to improve our productivity by changing our way of API design, sharing and development.&lt;/p&gt;

&lt;h2&gt;
  
  
  RPC v.s. Restful
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;The Representational State Transfer (REST) style is an abstraction of the architectural elements within a distributed hypermedia system. - Roy Thomas Fielding.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A RESTful API focuses on the resources that an API client can require from the API service. It is resouce based and usually performs CRUD operations on resource endpoints. A typical RESTful API usually looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;POST /users/501/messages HTTP/1.1
Host: api.example.com
Content-Type: application/json

&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"message"&lt;/span&gt;: &lt;span class="s2"&gt;"Hello!"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;In Contrast, RPC API is action based, which only have &lt;em&gt;get&lt;/em&gt; and &lt;em&gt;post&lt;/em&gt; functions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;POST /SendUserMessage HTTP/1.1
Host: api.example.com
Content-Type: application/json

&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"userId"&lt;/span&gt;: 501, &lt;span class="s2"&gt;"message"&lt;/span&gt;: &lt;span class="s2"&gt;"Hello!"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;

In Contrast, RPC API is action based, which only have &lt;span class="k"&gt;*&lt;/span&gt;get&lt;span class="k"&gt;*&lt;/span&gt; and &lt;span class="k"&gt;*&lt;/span&gt;post&lt;span class="k"&gt;*&lt;/span&gt; functions.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use RESTful to replace RPC?
&lt;/h3&gt;

&lt;p&gt;Let`s examine the following example to see if it a good solution. &lt;/p&gt;

&lt;h4&gt;
  
  
  RESTful Approach
&lt;/h4&gt;

&lt;p&gt;Imagine we are developing a library system that needs to handle the status of titles. When the library admin needs to update the status of tiltles, you may provide APIs like below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;POST /titles/123/in&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POST /titles/123/out&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POST /titles/123/suspended&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`shell&lt;br&gt;
PATCH /titles/123 HTTP/1.1&lt;br&gt;
Host: api.example.com&lt;br&gt;
Content-Type: application/json&lt;/p&gt;

&lt;p&gt;{"status": "Out"}&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;There is a problem that you want to update mutilple titles in batch and want to add background logic when you update a specific status. For example, when you want to set a title to state of "In" and notify all the readers that are in the wating list. &lt;/p&gt;

&lt;h4&gt;
  
  
  RPC Approach
&lt;/h4&gt;

&lt;p&gt;You can design your API with action based RPC Post function. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
POST /api/titles.transition_state HTTP/1.1&lt;br&gt;
Host: api.example.com&lt;br&gt;
Content-Type: application/json&lt;/p&gt;

&lt;p&gt;{&lt;br&gt;
  "title": "123",&lt;br&gt;
  "status": "Out",&lt;br&gt;
  "user": "U123,U234"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;By examples above, you can clearly see the benefits to design you API contract in a hybrid way. For resources, you can expose RESTful API to allow your API consumers to perform CRUD actions, and for the cases that requires background logic and data manapulation, the RPC approach is a better solution. &lt;/p&gt;

&lt;h2&gt;
  
  
  Why IDL matters
&lt;/h2&gt;

&lt;p&gt;Now, let`s consider how to define a API contract. IDL (Interface Definition Language) is a must for developers to share the API specification. There are multiple reasons including:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;IDL can be used to generate code artifacts.&lt;/li&gt;
&lt;li&gt;IDL has no ambiguity.&lt;/li&gt;
&lt;li&gt;IDL can be better managed in a VSC system (Github is my favorite).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I recommend protobuf as our IDL to define the API contract for reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Protobuf can be used to generate the OpenAPI specification, whereas the OpenAPI cannot be used reversely.&lt;/li&gt;
&lt;li&gt;Protobuf is widely used in the most popular RPC framework gRPC, which is actively developed and maitained by Google and community.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>idl</category>
      <category>grpc</category>
      <category>api</category>
    </item>
    <item>
      <title>How to debug your Go application in VSCode</title>
      <dc:creator>Hui`s Journal of Technology</dc:creator>
      <pubDate>Wed, 23 Mar 2022 02:04:07 +0000</pubDate>
      <link>https://dev.to/huihzhao/how-to-debug-your-go-application-in-vscode-3nfg</link>
      <guid>https://dev.to/huihzhao/how-to-debug-your-go-application-in-vscode-3nfg</guid>
      <description>&lt;p&gt;I am using VScode as my primary editor of coding, and I feel very excited by the VScode ecosystem. However, when I first used it to debug go application, as the debug settings is not that straightforward, I spent one hour to learn how to setup the debug process with VScode. &lt;/p&gt;

&lt;p&gt;Before you start, it'd better to install the dlv, the go debugger, manually.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install dlv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validate your dlv installation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dlv version
Delve Debugger
Version: 1.8.2
Build: $Id: dbb493ec14d1e7753504d016b1e1ef1665b75b16 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open VSCode in your root directory of your go project. Usually, in the root directory, you can find your main.go, go.mod, and go.sum files. &lt;/p&gt;

&lt;p&gt;Open your debug settings, which is a launch.json file saved in your code directory of ".vscode". &lt;/p&gt;

&lt;p&gt;Add the following contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch file",
            "type": "go",
            "request": "launch",
            "mode": "debug",
            "program": "main.go",
            "args": ["arg1", "arg2"]
        }

    ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can start your debugging by press "F5" now.&lt;/p&gt;

</description>
      <category>go</category>
      <category>vscode</category>
      <category>dlv</category>
    </item>
    <item>
      <title>Create docker image on your new MacBook Pro M1 version</title>
      <dc:creator>Hui`s Journal of Technology</dc:creator>
      <pubDate>Thu, 17 Mar 2022 14:10:34 +0000</pubDate>
      <link>https://dev.to/huihzhao/create-docker-image-on-your-new-macbook-pro-m1-version-4nid</link>
      <guid>https://dev.to/huihzhao/create-docker-image-on-your-new-macbook-pro-m1-version-4nid</guid>
      <description>&lt;p&gt;I just changed my major work laptop to the new MacBook Pro M1 Pro version. I really love this new machine as it can work almost 10 hours without charging. However, as a developer and product manager, sometimes I feel annoyed because of the new architecture.  &lt;/p&gt;

&lt;p&gt;Recently I work on a open source project and I am trying to optimize the developer experience of this project to allow developers use docker image to execute the CLI, which avoids installing lots of dependencies on developers` laptop. &lt;/p&gt;

&lt;p&gt;However, I found I need create a separate Dockerfile for my new Apple M1 Mac. &lt;/p&gt;

&lt;p&gt;First, the x86_64 base image cannot be used anymore, I have to explicitly use arm64 version base image. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
FROM --platform=arm64 ubuntu&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Secondly, I have to add lots of IF statements to detect the architecture of the host. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
arch=&lt;/code&gt;uname -m&lt;code&gt;&lt;br&gt;
    if [[ "${arch}" == "arm64" ]]; then&lt;br&gt;
        if [[ "$OSTYPE" == "darwin"* ]]; then&lt;br&gt;
            //add your logic here&lt;br&gt;
        fi&lt;br&gt;
        if [[ "$OSTYPE" == "linux"* ]]; then&lt;br&gt;
            //add your logic here&lt;br&gt;
        fi&lt;br&gt;
    fi&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Finally, I have to create arm64 version Dockerfile and build image with this file on my M1 Mac. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
docker build -t xxx . -f Dockerfile.arm64&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It will be great if you can give me a better solution. &lt;/p&gt;

</description>
      <category>newmacbookpro</category>
      <category>docker</category>
      <category>arm64</category>
    </item>
    <item>
      <title>Test gRPC services with gRPCurl</title>
      <dc:creator>Hui`s Journal of Technology</dc:creator>
      <pubDate>Wed, 16 Mar 2022 03:33:19 +0000</pubDate>
      <link>https://dev.to/huihzhao/test-grpc-services-with-grpcurl-3njf</link>
      <guid>https://dev.to/huihzhao/test-grpc-services-with-grpcurl-3njf</guid>
      <description>&lt;h1&gt;
  
  
  Test gRPC services with gRPCurl
&lt;/h1&gt;

&lt;p&gt;The gRPC functions can only be called by gRPC clients. My team just started migrating to gRPC stack, and I found gRPCCurl is a very helpful CLI tool to test and debug. &lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;grpcurl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Start your gRPC service and check the service metadata. My service is running on port of 10030.&lt;/p&gt;

&lt;p&gt;Use "-plaintext" if your service does not use TLS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;grpcurl &lt;span class="nt"&gt;-plaintext&lt;/span&gt; localhost:10030 describe
grpc.health.v1.Health is a service:
service Health &lt;span class="o"&gt;{&lt;/span&gt;
  rpc Check &lt;span class="o"&gt;(&lt;/span&gt; .grpc.health.v1.HealthCheckRequest &lt;span class="o"&gt;)&lt;/span&gt; returns &lt;span class="o"&gt;(&lt;/span&gt; .grpc.health.v1.HealthCheckResponse &lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  rpc Watch &lt;span class="o"&gt;(&lt;/span&gt; .grpc.health.v1.HealthCheckRequest &lt;span class="o"&gt;)&lt;/span&gt; returns &lt;span class="o"&gt;(&lt;/span&gt; stream .grpc.health.v1.HealthCheckResponse &lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
grpc.reflection.v1alpha.ServerReflection is a service:
service ServerReflection &lt;span class="o"&gt;{&lt;/span&gt;
  rpc ServerReflectionInfo &lt;span class="o"&gt;(&lt;/span&gt; stream .grpc.reflection.v1alpha.ServerReflectionRequest &lt;span class="o"&gt;)&lt;/span&gt; returns &lt;span class="o"&gt;(&lt;/span&gt; stream .grpc.reflection.v1alpha.ServerReflectionResponse &lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
sample_module.sample_package.SayHi is a service:
service SayHi &lt;span class="o"&gt;{&lt;/span&gt;
  rpc SayHello &lt;span class="o"&gt;(&lt;/span&gt; .sample_module.sample_package.HelloRequest &lt;span class="o"&gt;)&lt;/span&gt; returns &lt;span class="o"&gt;(&lt;/span&gt; .sample_module.sample_package.HelloReply &lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Call sample_module.sample_package.SayHi service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;grpcurl &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"msg": "jimmy"}'&lt;/span&gt; &lt;span class="nt"&gt;-plaintext&lt;/span&gt; localhost:10030 sample_module.sample_package.SayHi/SayHello
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"msg"&lt;/span&gt;: &lt;span class="s2"&gt;"SayHijimmy"&lt;/span&gt;,
  &lt;span class="s2"&gt;"code"&lt;/span&gt;: &lt;span class="s2"&gt;"1"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>grpc</category>
      <category>protobuf</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
