<?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: Sonia</title>
    <description>The latest articles on DEV Community by Sonia (@zoun).</description>
    <link>https://dev.to/zoun</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%2F523227%2F550e31ad-e370-4abe-9a4c-837d97594824.jpg</url>
      <title>DEV Community: Sonia</title>
      <link>https://dev.to/zoun</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zoun"/>
    <language>en</language>
    <item>
      <title>Deploy a Next.js application on AWS using CDK &amp; Fargate</title>
      <dc:creator>Sonia</dc:creator>
      <pubDate>Wed, 08 Sep 2021 11:55:50 +0000</pubDate>
      <link>https://dev.to/zoun/deploy-a-next-js-application-on-aws-using-cdk-fargate-2dnh</link>
      <guid>https://dev.to/zoun/deploy-a-next-js-application-on-aws-using-cdk-fargate-2dnh</guid>
      <description>&lt;h3&gt;
  
  
  What is Fargate ?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1628770733808%2FERXH8uhVs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1628770733808%2FERXH8uhVs.png" alt="Capture d’écran 2021-08-12 à 14.18.30.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Next.js on AWS ?
&lt;/h3&gt;

&lt;p&gt;The Next.js documentation says : &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The easiest way to deploy Next.js to production is to use the Vercel platform from the creators of Next.js&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well, if you are just getting started with your project, i will say go for Vercel.&lt;/p&gt;

&lt;p&gt;But in my case, i had all my projects on AWS using CDK, and i don't wanted to have to manage my Next.js app on another platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's get started
&lt;/h3&gt;

&lt;p&gt;Let's create the main folder of the project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir nextJsOnAws
cd nextJsOnAws
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  NextJS part
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-next-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and name it the way you want (i named it front)&lt;/p&gt;

&lt;p&gt;We are going to create a Dockerfile ( i am using the  &lt;a href="https://nextjs.org/docs/deployment#docker-image" rel="noopener noreferrer"&gt;official&lt;/a&gt;  one from the Vercel documentation)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Install dependencies only when needed

FROM node:alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile

# Rebuild the source code only when needed

FROM node:alpine AS builder
WORKDIR /app
COPY . .
COPY --from=deps /app/node_modules ./node_modules
RUN yarn build &amp;amp;&amp;amp; yarn install --production --ignore-scripts --prefer-offline

# Production image, copy all the files and run next

FROM node:alpine AS runner
WORKDIR /app

ENV NODE_ENV production

RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001


COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json

USER nextjs

EXPOSE 3000

CMD ["yarn", "start"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  CDK part
&lt;/h4&gt;

&lt;p&gt;Let's create a new CDK project on a dedicated folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir cdkPart
cd cdkPart
cdk init --language typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then let's install the package we need&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @aws-cdk/aws-ec2 @aws-cdk/aws-ecs @aws-cdk/aws-ecs-patterns
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the lib folder, a file was created called cdk_part-stack, open it and complete it like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as cdk from '@aws-cdk/core';
import * as ec2 from "@aws-cdk/aws-ec2";
import * as ecs from "@aws-cdk/aws-ecs";
import * as ecs_patterns from "@aws-cdk/aws-ecs-patterns";
import { DockerImageAsset } from "@aws-cdk/aws-ecr-assets";

export class CdkPartStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

 const APP_PORT = 3000
 const pathToDockerFile = "../front"

    const vpc = new ec2.Vpc(this, "MyVpc", {
      maxAzs: 2,
    });

    const taskDefinition = new ecs.FargateTaskDefinition(this, "MyTaskDefinition", {
      memoryLimitMiB: 512,
      cpu: 256,
    });

    const dockerFile = new DockerImageAsset(this, 'DockerFileAsset', {
      directory: pathToDockerFile,
      file: 'Dockerfile',
    });

    // cdk will build it and push it to en ecr repository
    const image = ecs.ContainerImage.fromDockerImageAsset(dockerFile);

    const container = taskDefinition.addContainer("MyContainer", {
      image,
      // store the logs in cloudwatch 
      logging: ecs.LogDriver.awsLogs({ streamPrefix: "myexample-logs" })
    });

    container.addPortMappings({
      containerPort: APP_PORT, 
    });

    const cluster = new ecs.Cluster(this, "MyECSCluster", {
      clusterName: "MyECSCluster",
      containerInsights: true,
      vpc,
    });

    const securityGroup = new ec2.SecurityGroup(this, `My-security-group`, {
      vpc: vpc,
      allowAllOutbound: true,
      description: 'My Security Group'
    });

    securityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(APP_PORT));

    const fargateService = new ecs_patterns.ApplicationLoadBalancedFargateService(this, 'MyFargateService', {
      cluster,
      publicLoadBalancer: true,
      cpu: 256,
      desiredCount: 1,
      memoryLimitMiB: 512,
      taskDefinition,
      securityGroups: [securityGroup]
    })

    const scalableTarget = fargateService.service.autoScaleTaskCount({
      minCapacity: 1,
      maxCapacity: 2
    })

    scalableTarget.scaleOnCpuUtilization('cpuScaling', {
      targetUtilizationPercent: 70
    })
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now time for deploy&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cdk synth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then after that :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cdk deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The deploy can be a little long , so be patient :) &lt;/p&gt;

&lt;h3&gt;
  
  
  Let's go to the console
&lt;/h3&gt;

&lt;p&gt;After the deploy is completed, go to your AWS Console &amp;gt; ECS (for Elastic Container Service)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629308029943%2FhS9F6JDe2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629308029943%2FhS9F6JDe2.png" alt="Capture d’écran 2021-08-18 à 19.32.59.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on MyECSCluster&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629308068125%2F9SIjePWlE.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629308068125%2F9SIjePWlE.png" alt="Capture d’écran 2021-08-18 à 19.34.07.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the service&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629308120568%2FBKEqT1rTl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629308120568%2FBKEqT1rTl.png" alt="Capture d’écran 2021-08-18 à 19.34.53.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the Task Tab&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629308170683%2FNfIAkm89d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629308170683%2FNfIAkm89d.png" alt="Capture d’écran 2021-08-18 à 19.35.03.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the Task&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629308267543%2FwfRWylVQpW.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629308267543%2FwfRWylVQpW.png" alt="Capture d’écran 2021-08-18 à 19.37.35.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see that your container is ... RUNNING :) &lt;/p&gt;

&lt;h3&gt;
  
  
  Let's see the app !!!
&lt;/h3&gt;

&lt;p&gt;Go to the console &amp;gt; EC2 &amp;gt; LoadBalancer and copy the DNS name of your load balancer&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629308377424%2Ffd4DmwfWw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629308377424%2Ffd4DmwfWw.png" alt="Capture d’écran 2021-08-18 à 19.38.43.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Paste it in your browser and ... &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629308422041%2FVcSSwju0T.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629308422041%2FVcSSwju0T.png" alt="Capture d’écran 2021-08-18 à 19.40.10.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congrats ! You deployed your Next.js app with Fargate and it's running :) &lt;/p&gt;

&lt;h3&gt;
  
  
  Cleaning
&lt;/h3&gt;

&lt;p&gt;Don't forget to clean after this tutorial, i don't want you to have a huge bill on AWS!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cdk destroy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope you liked this tutorial, i will try my best to post some articles about AWS.&lt;/p&gt;

&lt;p&gt;If you want, you can follow me on Twitter :) &lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Create a simple GraphQL API with Node JS</title>
      <dc:creator>Sonia</dc:creator>
      <pubDate>Sun, 14 Feb 2021 10:21:43 +0000</pubDate>
      <link>https://dev.to/zoun/create-a-simple-graphql-api-with-node-js-323h</link>
      <guid>https://dev.to/zoun/create-a-simple-graphql-api-with-node-js-323h</guid>
      <description>&lt;p&gt;I used for the first time GraphQL a few days ago and i wanted to share with you what i learned.&lt;/p&gt;

&lt;p&gt;In this project, we are going to use GraphQL for one of my favorite Tv Shows : Friends !&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1612635511996%2FXZuDwnrkI.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1612635511996%2FXZuDwnrkI.jpeg" alt="11103892_f57d05a21e.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's get started
&lt;/h3&gt;

&lt;p&gt;Create a new project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir mygraphQlApi
cd mygraphQlApi
npm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are going to use : &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Koa
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install koa --save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install koa-bodyparser koa-helmet koa-router --save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Knex and Knex CLI
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install knex -g
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install knex@0.13.0 -g
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Postgres
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install pg --save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;GraphQL
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install graphql graphql-tools apollo-server-koa --save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
   Create the Database
&lt;/h3&gt;

&lt;p&gt;We are going to connect to Postgres&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo -u postgres psql postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create the database&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;postgres=# CREATE DATABASE friends;

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

&lt;/div&gt;



&lt;p&gt;List your databases to see your new DB just created&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;postgres=# \list

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                                   List of databases
    Name     |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
-------------+----------+----------+-------------+-------------+-----------------------
 friends     | postgres | UTF8     | fr_FR.UTF-8 | fr_FR.UTF-8 | 
 postgres    | postgres | UTF8     | fr_FR.UTF-8 | fr_FR.UTF-8 | 
 template0   | postgres | UTF8     | fr_FR.UTF-8 | fr_FR.UTF-8 | =c/postgres          +
             |          |          |             |             | postgres=CTc/postgres
 template1   | postgres | UTF8     | fr_FR.UTF-8 | fr_FR.UTF-8 | =c/postgres          +
             |          |          |             |             | postgres=CTc/postgres

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

&lt;/div&gt;



&lt;p&gt;Finally create a user with a password&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE USER myusername WITH PASSWORD 'password';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Connect to your DB&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;psql -h localhost -d friends -U myusername
Password for user myusername: 


friends=&amp;gt; 

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

&lt;/div&gt;



&lt;p&gt;Everything is fine ! &lt;/p&gt;

&lt;p&gt;Type  \q to quit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Back to the project
&lt;/h3&gt;

&lt;p&gt;We are going to create a folder called knex and some subfolders for our seeds, migrations and queries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir knex
mkdir knex/migrations
mkdir knex/seeds
mkdir knex/queries
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, to store some data, we are goind to create a folder called data, with a cast.js file inside that folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir data
cd data
touch cast.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Initiate the project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;knex init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will create a file called knex.js&lt;br&gt;&lt;br&gt;
Let's modify the file like this :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
 development: {
  client: 'pg',
  connection: 'postgres://username:password@localhost:5432/database',
  migrations: {
      directory: __dirname + '/knex/migrations',
    },
    seeds: {
      directory: __dirname + '/knex/seeds'
    }
 }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NB : Replace the username, password and database value with the right ones.  &lt;/p&gt;

&lt;p&gt;Now your project should look like this &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1612719985290%2F2wykNbT8P.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1612719985290%2F2wykNbT8P.png" alt="Capture d'écran 2021-02-07 18:46:02.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Database is empty !
&lt;/h3&gt;

&lt;p&gt;For now, you have a database, but with no data ! Let's fix that !  &lt;/p&gt;

&lt;p&gt;First , let's create a table on the DB.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;knex migrate:make cast
Using environment: development
Created Migration: /path/of/your/project/knex/migrations/20210207185018_cast.js

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

&lt;/div&gt;



&lt;p&gt;This command is going to create a migration file, let's modify it like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exports.up = (knex) =&amp;gt; Promise.all([
    knex.schema.createTable('cast', function(table) {
        table.increments();
        table.string('firstName').notNullable();
        table.string('lastName').notNullable();
        table.string('Food').notNullable();
    })
]);

exports.down = (knex) =&amp;gt; {
return knex.schema.dropTable('cast');
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's "run" the migration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;knex migrate:latest --env development
Using environment: development
Batch 1 run: 1 migrations

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

&lt;/div&gt;



&lt;p&gt;Now that we have a table, let's fill it with some data.&lt;br&gt;
We are going to "seed" the table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;knex seed:make cast_seed
Using environment: development
Created seed file:/path/of/your/project/knex/seeds/cast_seed.js

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

&lt;/div&gt;



&lt;p&gt;In the data folder, go to your cast.js file and complete it like this :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = [
    {
      "firstName": "Chandler",
      "lastName": "Bing",
      "Food": "Cheesecake"
    },
    {
        "firstName": "Monica",
        "lastName": "Geller",
        "Food": "Mint Cookies"
    },
    {
        "firstName": "Joey",
        "lastName": "Tribiani",
        "Food": "Pizza"
    }
];

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

&lt;/div&gt;



&lt;p&gt;Complete your seed file like this to seed the DB with the data from your file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const castData = require('../../data/cast');

exports.seed = function(knex) {
  // Deletes ALL existing entries
  return knex('cast').del()
    .then(function () {
      // Inserts seed entries
      return knex('cast').insert(castData);
    });
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's now run this command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;knex seed:run --env development
Using environment: development
Ran 1 seed files

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

&lt;/div&gt;



&lt;p&gt;Let's connect to the DB, to see 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;psql -h localhost -d friends -U myusername
Password for user myusername: 

friends=&amp;gt; SELECT * FROM public.cast;
 id | firstName | lastName |    Food     
----+-----------+----------+-------------
  1 | Chandler  | Bing     | Cheesecake
  2 | Monica    | Geller   | MintCookies
  3 | Joey      | Tribiani | Pizza
(3 rows)

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

&lt;/div&gt;



&lt;p&gt;Congrats, you have now a DB, with a table called cast, and some data in that table! &lt;/p&gt;

&lt;p&gt;Next step, the GraphQL part ! &lt;/p&gt;

&lt;h3&gt;
  
  
  GraphQL part
&lt;/h3&gt;

&lt;p&gt;Now let's make the GraphQL part.  &lt;/p&gt;

&lt;p&gt;Let's create a file called index.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Koa = require('koa');
const { ApolloServer, gql } = require('apollo-server-koa');
const queries = require('./knex/queries/queries.js');

const typeDefs = gql`
  type Cast {
    firstName: String
    lastName: String
    Food: String
  }
  type Query {
    cast(firstName: String, lastName: String, Food: String): [Cast]
  }
`;

const schema = {
  typeDefs,
  resolvers: {
    // Prototypes for GET 
    Query: {
      cast: (_, filters) =&amp;gt; queries.getCast(filters),
    }
  }
}

const server = new ApolloServer(schema);

const app = new Koa();
server.applyMiddleware({ app });

app.listen({ port: 3000 }, () =&amp;gt;
  console.log(`🚀 Server ready at http://localhost:3000${server.graphqlPath}`),
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see line 3, we are using queries , let's create them : &lt;/p&gt;

&lt;p&gt;In the knex folder, we created a folder called queries. Let's create a file called queries.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd knex/queries
touch queries.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const knex = require('../connect');

function getCast(filters) {
  return knex('cast')
  .select('*')
  .where(filters);
}

module.exports = {
  getCast
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let create the connect file used on the first line&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ../
touch connect.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const environment = process.env.NODE_ENV || 'development';
const config = require('../knexfile.js')[environment];

module.exports = require('knex')(config);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's start our server&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node index.js
🚀 Server ready at http://localhost:3000/graphql

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

&lt;/div&gt;



&lt;p&gt;You should see something like this &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1613239844589%2Fv40dr3rq1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1613239844589%2Fv40dr3rq1.png" alt="Capture d'écran 2021-02-13 19:10:00.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Query some data
&lt;/h3&gt;

&lt;p&gt;Let's try to query some data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Write your query or mutation here
query Everyone {
  cast {
    firstName
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Click on the Play button&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "data": {
    "cast": [
      {
        "firstName": "Chandler"
      },
      {
        "firstName": "Monica"
      },
      {
        "firstName": "Joey"
      }
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tadaaaam ! You have made your first query with GraphQL ! &lt;/p&gt;

&lt;h3&gt;
  
  
  Let's add some characters
&lt;/h3&gt;

&lt;p&gt;But wait a minute ... where is Ross ? and Rachel ? And Phoebe ? &lt;/p&gt;

&lt;p&gt;We need to add them to our database.&lt;/p&gt;

&lt;p&gt;Let's use Mutations for that.&lt;/p&gt;

&lt;p&gt;In your index.js file, let's update the schema to add Mutations&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# index.js
const typeDefs = gql`
  type Cast {
    firstName: String
    lastName: String
    Food: String
  }
  type Query {
    cast(firstName: String, lastName: String, Food: String): [Cast]
  }
  type Mutation {
  addSomeone(firstName: String, lastName: String, Food: String): [Cast]
}
`;

const schema = {
  typeDefs,
  resolvers: {
    // Prototypes for GET 
    Query: {
      cast: (_, filters) =&amp;gt; queries.getCast(filters),
    },
    // Prototypes for PUT
    Mutation: {
        addSomeone: async (_, cast) =&amp;gt; {
          const newOne = await queries.addSomeone(cast);

          return newOne;
        }
      }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then in the queries.js file, let's create the actual queries for those mutations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# queries.js

const knex = require('../connect');

function getCast(filters) {
  return knex('cast')
  .select('*')
  .where(filters);
}

function addSomeone(cast) {
    return knex('cast')
    .insert({
      firstName: cast.firstName,
      lastName: cast.lastName,
      Food: cast.Food
    })
    .returning('*');
}

module.exports = {
  getCast,
  addSomeone
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart our server and write a Mutation to add Ross&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mutation addRoss{
  addSomeone(firstName: "Ross", lastName: "Geller", Food: "Turkey Sandwich") {
    firstName
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hit the play button&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "data": {
    "addSomeone": [
      {
        "firstName": "Ross"
      }
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's query all the cast once again&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Write your query or mutation here
query Everyone {
  cast {
    firstName
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Click on play ... and cross fingers&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "data": {
    "cast": [
      {
        "firstName": "Chandler"
      },
      {
        "firstName": "Monica"
      },
      {
        "firstName": "Joey"
      },
      {
        "firstName": "Ross"
      }
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yeaaaah ! Now you can add all the others ! &lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;I just started learning GraphQL so i probably made some mistakes, i am still figuring out how to make everything work but i wanted to share this first milestone with you ! &lt;/p&gt;

&lt;p&gt;If you have some tips or resources to help me keep digging the subject, drop them on the comments ! &lt;/p&gt;

&lt;p&gt;The full code is here on GIthub :  &lt;a href="https://github.com/SoniaisMad/graphQL-node" rel="noopener noreferrer"&gt;Code&lt;/a&gt; &lt;/p&gt;

</description>
      <category>node</category>
      <category>graphql</category>
      <category>beginners</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Do you suffer with the "too-many-tabs" syndrome ? OneTab is the solution !</title>
      <dc:creator>Sonia</dc:creator>
      <pubDate>Fri, 25 Dec 2020 19:20:33 +0000</pubDate>
      <link>https://dev.to/zoun/do-you-suffer-with-the-too-many-tabs-syndrome-onetab-is-the-solution-gap</link>
      <guid>https://dev.to/zoun/do-you-suffer-with-the-too-many-tabs-syndrome-onetab-is-the-solution-gap</guid>
      <description>&lt;h2&gt;
  
  
  Tabs, tabs, tabs
&lt;/h2&gt;

&lt;p&gt;I always like to read stuff, and listen to podcasts.&lt;/p&gt;

&lt;p&gt;So when i find something i'm interested in, i open a tab on my browser and i leave it there for ... later.&lt;/p&gt;

&lt;p&gt;And then, i move on to the next thing, and i find another super article on Hashnode.&lt;/p&gt;

&lt;p&gt;So i open a new tab, to read it ... later.&lt;/p&gt;

&lt;p&gt;And someone on Twitter posts a link to a new podcast episode, so i open a new tab on my browser and save it for later.&lt;/p&gt;

&lt;p&gt;And in the same time, i have to review some PRs on Github.&lt;/p&gt;

&lt;p&gt;So i open a tab for each one, to remember to do it ... later.&lt;/p&gt;

&lt;p&gt;And someone on Slack sends me a new Jira Card, so i open a new tab for it ...&lt;/p&gt;

&lt;p&gt;And so on ...&lt;/p&gt;

&lt;p&gt;Before lunch, my browser looks like this : &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Shb2KzDF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1608025733204/ut6EyX1II.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Shb2KzDF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1608025733204/ut6EyX1II.png" alt="tabs.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if you use Chrome, you know that more and more tabs === more and more RAM.&lt;/p&gt;

&lt;p&gt;Sometimes, my computer slows down, just because i have too many tabs...&lt;/p&gt;

&lt;h2&gt;
  
  
  THE SOLUTION : OneTab extension
&lt;/h2&gt;

&lt;p&gt;Someone at work recommended me this extension after seeing my shared screen on a Zoom meeting ...&lt;/p&gt;

&lt;p&gt;One Tab is an extension available for Chrome and Firefox.&lt;/p&gt;

&lt;p&gt;Once installed, when you click on it ... tadaaaam : &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DaCqv6Zc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1608026706950/-Oo6jRnPa.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DaCqv6Zc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1608026706950/-Oo6jRnPa.jpeg" alt="one-tab-header.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It takes all your tabs and make it just one which contains the list of all your links !&lt;/p&gt;

&lt;p&gt;And also, you can organise your links by naming the lists, so you can have a list with all your "Work" links, and another one for "Tech stuff" ...&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it !
&lt;/h2&gt;

&lt;p&gt;Here are the links to download the extension : &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;On  &lt;a href="https://chrome.google.com/webstore/detail/onetab/chphlpgkkbolifaimnlloiipkdnihall"&gt;Chrome&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On  &lt;a href="https://addons.mozilla.org/fr/firefox/addon/onetab/"&gt;Firefox&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And their  &lt;a href="https://www.one-tab.com/"&gt;Website&lt;/a&gt; &lt;/p&gt;

</description>
      <category>extension</category>
      <category>browser</category>
      <category>chrome</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Automating your routine with Golang and a CLI</title>
      <dc:creator>Sonia</dc:creator>
      <pubDate>Mon, 30 Nov 2020 15:09:27 +0000</pubDate>
      <link>https://dev.to/zoun/automating-your-routine-with-golang-and-a-cli-4dok</link>
      <guid>https://dev.to/zoun/automating-your-routine-with-golang-and-a-cli-4dok</guid>
      <description>&lt;p&gt;I had this idea after reading the article of @&lt;a href="https://dev.to@dailydevtips"&gt;Chris Bongers&lt;/a&gt; about  &lt;a href="https://h.daily-dev-tips.com/ive-automated-my-morning-routine" rel="noopener noreferrer"&gt;automating morning routine&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;I read that article and loved the idea to automate some tasks that we do everyday.&lt;/p&gt;

&lt;p&gt;So i decided to take a step further and create a CLI who is gonna be my "assistant" to make all kind of small tasks.&lt;/p&gt;

&lt;p&gt;In this tutorial, we are going to make a CLI in Golang to do two things : &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open tabs on my browser (like Chris Bongers did with a script but we are gonna do it with Golang)&lt;/li&gt;
&lt;li&gt;Create and saves txt notes from the CLI.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;You must have a little knowledge about Golang to follow this tutorial.&lt;/p&gt;

&lt;p&gt;To create the CLI, we are going to use  &lt;a href="https://github.com/spf13/cobra" rel="noopener noreferrer"&gt;Cobra&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Cobra is a library for creating CLI in golang.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create the project
&lt;/h2&gt;

&lt;p&gt;Now we can start.&lt;/p&gt;

&lt;p&gt;We are going to create a new project on our computer&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir mycli
cd mycli
go mod init mycli
go get -u github.com/spf13/cobra/cobra
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  init the CLI
&lt;/h2&gt;

&lt;p&gt;Now that we have cobra installed, we can start creating our cli&lt;/p&gt;

&lt;p&gt;The pkg-name here is important because it's going to be the name you invoke when calling your CLI. I'm gonna call mine Homer&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cobra init --pkg-name homer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After executing that command , you can see that your project-folder looks like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;▾ mycli/
  ▾ cmd/
     root.go
   main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create our first command
&lt;/h2&gt;

&lt;p&gt;Now let's add our first command to our cli&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cobra add &amp;lt;commandName&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our first command is to open tabs in the morning, so i am gonna type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cobra add morning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you look at your files structure, a new file called morning.go has been created.&lt;br&gt;
Every time you are gonna add a command, a new file with the name of your command is gonna be created in the cmd folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;▾ mycli/
  ▾ cmd/
     root.go
     morning.go
   main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Implement the morning command
&lt;/h2&gt;

&lt;p&gt;Now, open the file called morning.go&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package cmd

import (
    "fmt"

    "github.com/spf13/cobra"
)

// morningCmd represents the morning command
var morningCmd = &amp;amp;cobra.Command{
    Use:   "morning",
    Short: "A brief description of your command",
    Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("morning called")
    },
}

func init() {
    rootCmd.AddCommand(morningCmd)

    // Here you will define your flags and configuration settings.

    // Cobra supports Persistent Flags which will work for this command
    // and all subcommands, e.g.:
    // morningCmd.PersistentFlags().String("foo", "", "A help for foo")

    // Cobra supports local flags which will only run when this command
    // is called directly, e.g.:
    // morningCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

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

&lt;/div&gt;



&lt;p&gt;We are going to work inside the &lt;code&gt;var morningCmd&lt;/code&gt; that represents our command.&lt;/p&gt;

&lt;p&gt;First, complete the use and the descriptions (long and short) of your command.&lt;/p&gt;

&lt;p&gt;Then, inside the Run , we are going to implement the actual code that we want to run when we are going to call the command : &lt;code&gt;homer morning&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package cmd

import (
    "bufio"
    "fmt"
    "os"

    "github.com/spf13/cobra"
    "github.com/pkg/browser"
)

// morningCmd represents the morning command
var morningCmd = &amp;amp;cobra.Command{
    Use:   "morning",
    Short: "Open a list of urls",
    Long: `Url opens a list of urls defined in a txt file`,
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("Good morning ! Homer is opening your tabs")
        // Open the file.
        f, _ := os.Open("/path/to/your/tabs.txt")
        // Create a new Scanner for the file.
        scanner := bufio.NewScanner(f)
        // Loop over all lines in the file and print them.
        for scanner.Scan() {
          line := scanner.Text()
          // use browser to Open the url
          browser.OpenURL(line)
        }
    },
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great ! &lt;br&gt;
Now let's build our app &lt;/p&gt;

&lt;p&gt;&lt;code&gt;go install homer&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And try our command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;homer morning
Good morning ! Homer is opening your tabs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tadaaaaaam ! &lt;/p&gt;

&lt;h2&gt;
  
  
  Let's add another command
&lt;/h2&gt;

&lt;p&gt;Well, now let's go further and add another command.&lt;/p&gt;

&lt;p&gt;Let's add a command to take quick notes.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cobra add notes&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;A new file called notes.go is now available.&lt;/p&gt;

&lt;p&gt;Let's implement the code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package cmd

import (
    "fmt"
    "os"
    "os/exec"

    "github.com/spf13/cobra"
)

// notesCmd represents the notes command
var notesCmd = &amp;amp;cobra.Command{
    Use:   "notes",
    Short: "A command to take quick notes",
    Long: `This command helps you take quick notes by opening a file .txt`,
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("Homer is opening a new note")
        // create a folder for the notes if doesn't exists
        _ = os.Mkdir("./notes", 0755)
        // open the editor of your choice =&amp;gt; nano for me
        // the name of the file will be your argument
        // homer notes myfile will open a file called myfile.txt 
        editorCmd := exec.Command("nano", fmt.Sprintf("./notes/%v.txt", args[0]))
        editorCmd.Stdin = os.Stdin
        editorCmd.Stdout = os.Stdout
        editorCmd.Stderr = os.Stderr

        err := editorCmd.Run()
        if (err != nil) {
            fmt.Println(err)
        }
    },
}

func init() {
    rootCmd.AddCommand(notesCmd)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, build the app : &lt;code&gt;go install homer&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And run the command &lt;/p&gt;

&lt;p&gt;&lt;code&gt;homer notes mynote&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1606652530171%2FIz4mVyJxx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1606652530171%2FIz4mVyJxx.png" alt="Capture d'écran 2020-11-29 13:21:46.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just write your note and save it.&lt;/p&gt;

&lt;p&gt;All your notes will be saved inside the folder notes.&lt;br&gt;&lt;br&gt;
I chose to put it inside the project (./notes) but you can choose to create it wherever you want on your computer.&lt;/p&gt;

&lt;h2&gt;
  
  
  And now ?
&lt;/h2&gt;

&lt;p&gt;Now you have a new assistant called homer that can do multiple tasks for you.&lt;br&gt;&lt;br&gt;
So just think about a new task you want to automate, and make a new command with cobra.  &lt;/p&gt;

&lt;p&gt;For example, you can add subcommands to list all your notes, to find a particular note, to delete a note ...&lt;/p&gt;

&lt;p&gt;Have fun with your new assistant :) &lt;/p&gt;

</description>
      <category>go</category>
      <category>automation</category>
      <category>cli</category>
    </item>
  </channel>
</rss>
