Saturday, July 31, 2021

great repository for Tailwind css and Django

I am a big fan of Tailwind CSS. It is a great companion of Styled Component.

you should be able to find lots of useful resource for Tailwind CSS in this GitHub

https://github.com/aniftyco/awesome-tailwindcss


Tailblocks Ready to use Tailwind CSS Block

It is a great place to find the suitable CSS block to copy and paste in your project

https://tailblocks.cc/


a site with all Django package

https://djangopackages.org/


Save All Resources

https://chrome.google.com/webstore/detail/save-all-resources/abpdnfjocnmdomablahdcfnoggeeiedb/related?hl=en


Virtual Environment for django and python development

https://virtualenvwrapper.readthedocs.io/en/latest/


how to move the side bar to the right in visual studio code?

 I had work for Visual Studio since 2003 version. it is default by the side bar and explorer are located in the right hand side. However the side bar is shown in the left hand side of the visual studio code. I am really not used to be with the change of the location.

it is very easy to switch it to the one which is the right hand side. just right click  to the side bar, then select Move Side Bar Right menu item from the Menu.













Now it is back to the layout that I work most of the time.




how to setup template folder for Django development?

 there are two ways to setup the template folder for django development.

first we can setup the path that Django framework can automatically recognize it..

under the component folder, we have to create the a template folder, then create a folder with name matching the component name.

for example we have a lead component, then the structure of the project should look like as following








in the view.py, we can implement with the code snippet below

from django.shortcuts import render

# Create your views here.

def home_page(request):
    return render(request"leads/home_page.html")

second. we can modify the DIRS attribute in  TEMPLATES setting section in the settings.json to map to the templates path.

TEMPLATES = [
    {
        'BACKEND''django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates'],
        'APP_DIRS'True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

then we only have to create a templates folder under the current component folder. we can add the template html in the template folder.







in the view.py we use the template page directly.

def home_page(request):
    return render(request"home_page.html")








Friday, July 30, 2021

how to fix "Import "django.contrib.auth" could not be resolved from sourcePylance" in Django application development?

 when I try to import a library to the project. I spot a curly underline for the library that i just imported.

I hovered the mouse to the underneath, the warming message as following

    "Import "django.contrib.auth" could not be resolved from sourcePylance"


the root cause of this issue is related to the VS Code workspace configuration. we have to add this line to get ride of the error message.

{
    "python.pythonPath""/venv/bin/python",
}

Since I did not have the .vscode folder when I setup my django project with command line window.

I have to manually create a .vscode folder under the project and add the settings.json file inside it.

I put the above setting in the settings.json file.  The warming message finally resolved.










update: if the above solution still doesn't work

you can change the python interpreter for the current project by doing the following

  • use Ctrl-Shift-p to open command palette
  • type python interpreter in the command palette
  • select Enter interpreter path
  • find the python.exe file under your venv\scripts folder


How can we set restrictions on page in flask app?

 if we want to the user had to login to view the page.

we can use this decorator   @login_required to enforce only login user can access the page.

@app.route('/private')
@login_required
def private_page():
purchase_form = PurchaseItemForm()
if request.method == "POST":
purchased_item = request.form.get('purchased_item')
p_item_object = Item.query.filter_by(name=purchased_item).first()
if p_item_object:
if current_user.can_purchase(p_item_object):
p_item_object.buy(current_user)
flash(f"Congratulations! You purchased {p_item_object.name} for {p_item_object.price}$", category='success')
else:
flash(f"Unfortunately, you don't have enough money to purchase {p_item_object.name}!", category='danger')
return redirect(url_for('private_page'))
if request.method == "GET":
items = Item.query.filter_by(owner=None)
for item in items:
print(item.name)
return render_template('market.html', items=items, purchase_form=purchase_form)

Monday, July 26, 2021

how to implement dynamic routing in Flask

 When we want to pass into a variable on routing. we can use the following code to pass the variable <routeVariable> in the route path.

@app.route("/mypage/<username>"

def  my_page(username):

        return f"<h1>Hello {username}'s page<h1>"


the output is 

hello dan's page

how to force a flask web app to run on specific port in local development?

 when I execute flask run to launch the flask web app in my laptop. I usaully encoutered an error as following.

    "OSError: [WinError 10013] An attempt was made to access a socket in a way forbidden by its access permissions " 

since the windows firewall had block this port.

I can assign the port during the launch to void this issue. i assing 300 for this app.

flask run -h localhost -p 3000 

Saturday, July 24, 2021

Python Quick Reference

It is a quick reference for seasoned developer, who already master at least one programming language. for myself, I have worked with C# for more than 10+ years. this reference can help you easily translate from other language to python

Naming Variables : camel Case

    myVariable

Data Types: 

    Text Type: 

         str "hello world"

    Numeric Types: 

        int : (10),

        long :(101L)

        float: (10.01), 

        complex: (3j)

    Sequence Types:

        list: ["a","b","c","d"], 

        tuple: immutable 

        myTuple = ("a","b","c","d")  

       tuple[0]="New assignment"  TypeError: 'tuple' object does not support item assignment

        range: generate a sequence of integer

        range(5) : 0 1 2 3 4

        range(0, 5, 2) : 0 2 4

    Mapping Type: 

        dictionary: list of key value pairs

        myDictionary={"key1:value1, "key2:value2 }

    Set Types:

    set 

    frozenset

Boolean Type: bool

Binary Types: bytes, bytearray, memoryview

Comments

    # single comment

    """

    multiple line comments

    another line comments

    """

Strings

Multiline and Formatting Strings

Indentation

Arithmetic Operators

Comparison Operators

    <, >, <=, >=, ==, !=, <>

Logical Operators

    and, or, not

Assignment Operators

    a=b assign value from right to left

    a +=b a=a+b

    a -=b a=a-b

   a *=b a=a*b

    a /=b a=a/b

    a **=b a=a**b

    a //=b   a=a//b   10 //=3   => 10//3=3

 If Statements

    if condition:

    elif condition:

    else:

Ternary If Statements

    message= "true condition" if condition else "false condition"

Lists

    operators:

        Length: len([1, 2, 3] => 3

        Concatenation: ["a", "b", "c"] + [1, 2, 3]  => ["a", "b", "c", 1, 2, 3]

        Repetition: [a, b] * 3 => ["a", "b", "a", "b", "a", "b"]

        Slicing [1: ]   myList=[1,  2,  3] myList[1:] => [2, 3]

        Indexing :

        myList=[1,  2,  3]  

        offsets starting from zero:  myList[1] => 2

         if negative counting from the right side:  myList[-1] => 3

      Built in List methods 

          max(myList) =>3

          min(myList) => 1

         list: convert  iterable object into a list

         list("abcd")=>[a, b, c, d]

         list(123456) TypeError: 'int' object is not iterable

         list("123456") => [1, 2, 3, 4, 5 ,6]

         list({12, "ab", [1, 3]}) => [12, "ab", [1, 3]]

Useful List Methods

  • append : add item the end of the list
  • count: find the number of occurrence of object
  • extend: append iterable object to the list
  • insert: add item to the offset index
  • pop: return the item from the list
  • remove: remove item from the list
  • reverse: reverse the order of items in the list
  • sort: sort items in the list

Deleting Items from Lists

    del list(obj) exactly like list.remove(obj)

Sets

    not allow to have duplicate item

Set Union Intersection & Difference

    union : setA | setB

    intersect: setA & setB

    differece: setA - setB

    symmetric_difference: setA ^ setB

Dictionaries

    key value pairs data structure

   myDict ={

        "key1" : value1, 

        "key2" : value2,

        "key3" : value3

}

value1=myDict["key1"]

    Functions:

        len:

        

    Methods:

For Loops

    for item in list or set:

        print(item)

Loop Through Dictionaries

    for key in dict: 

        print(f"key: {key} value: {dict[key]}")

While Loop

    number=0

    while number < 3

         number +=1

Break and Continue

    break: exist the the loop if condition meets

              number=0

                while number < 3

                     if number==2

                        break;

                     number +=1

    continue: continue the loop if the condition is true

                       number=0

                            while number < 3

                     if number <=2

                            continue;

                            number +=1

Functions 

    def myfunction():

        print("this  is my first function")

Built in Functions and Import Statement

    import python module

        import math

    import specific method from the module

        from math import floor

Creating Modules

        create a python file myModule.py

        in another file use import myModule to reference the moudule

         printing all variables and function names of the "myModule" module

          dir(myModule)

Classes and Objects

    classes are the blueprints of objects

    objects are the instances of classes

Creating Classes and Objects

     class person

        #define the constructor

        def __init__(self, firstName,lastName):

                self.fistName=firstName

                self.lastName=lastName 

     myObject=person("first name", "last name")

 Inheritance

    class driver(person)  #driver is inherited from person

Printing Objects

    # override method

    def __str__(self) -> str:

           return f"last name: {self.firstName}, last name: {self.lastName}"

Working With Dates

    from datetime import datetime #work with datetime

    from datetime import date    #work with actual date

Formatting Dates

    now=datetime.now()

    now.strftime("datetime string formatter") 

Creating Files

    file =open("./myfile.txt", "w")      # create a text file myfile.txt in the current working dir

    flags: a -> append

              r -> read

              r+ -> read and write

              w -> write

    file.close() # to properly close the file being read or write    

Reading From Files

     file =open("./myfile.txt", "r") 

     file.read()

     file.close()

A Better Way To Work With Files

    import os.path

    if(os.path.isfile(myfile.txt):  #ensure the file exists before read write operations

            with open("./myfile.txt", "r")  as file

                file.read()

Fetching Data From Internet

     import json

    from urllib import request

    response = request.urlopen(("https://fakerapi.it/api/v1/companies?_quantity=5"))

    resjson = json.loads(response.read())

    print(resjson["data"])

Pip & Modules

    pip3: python package manager

    pip3 install requests

 Request Module

    import json

    import requests

    response = requests.get(("https://fakerapi.it/api/v1/companies?_quantity=5"))

    print(response.text)

    jsonData = json.loads(response.text)

    print(jsonData["data"])

Text To Speech

  pip3 install pyttsx3

   import pyttsx3

   pyttsx3.speak


Asterik * 

 * is argument-unpacking and ** keyword-argument-unpacking operators

The single star * unpacks the sequence/collection into positional arguments

The double start ** uses a dictionary and thus named arguments.



Tuesday, July 20, 2021

how to access the server error mesage from axios http call?

 Here is my call from my code to log the error from axios call.

export const signUp=(formDatahistory)=>async(dispatch=>{
    try{
        const {data}=await api.signUp(formData);
        dispatch({type: AUTHdata});
        history.push('/');
    }catch(error){
        console.log(error);
    }
}

in the express server I have the code to send back the error message to client.

export const signUp=async (reqres)=>{
    const {firstNamelastNameemailpasswordconfirmPassword} = req.body;
    const existingUser=await User.findOne({email});
    if(existingUser){
        return res.status(400).json({error: "User already exist!"});
    }
    if(password !== confirmPassword){
        return res.status(400).json({error: "Password do not match"});
    }
    const salt = bcrypt.genSaltSync(10);
    const hashPassword = bcrypt.hashSync(passwordsalt);

    try{
        const newUser = await User.create({ firstNamelastNameemail
            password:hashPasswordname:`${firstName} ${lastName}` });
        const token=jwt.sign({email: newUser.emailid: newUser._id}, 
            process.env.SECRET, {expiresIn: "1h"});
        res.status(200).json({result:newUsertoken});

    }catch(err){
        console.error(err.message);
        res.status(500).json({message: 'Something went wrong'});
    }
}

the console only show the following error message, which is not helpful to trouble shooting and represent to the user. the status code is logged, but the error message is not shown.

 return res.status(400).json({error: "User already exist!"});

Error: Request failed with status code 400 at createError (createError.js:16) at settle (settle.js:17) at XMLHttpRequest.handleLoad (xhr.js:62)


after I change the code to log the error.response, then we can finally get the error message back

export const signUp=(formDatahistory)=>async(dispatch=>{
    try{
        const {data}=await api.signUp(formData);
        dispatch({type: AUTHdata});
        history.push('/');
    }catch(error){
        console.log(error.response);
    }
}
  1. status400
  2. statusText"Bad Request"











Sunday, July 18, 2021

how to ensure the push of modification from local to GitHub always execute?

 Usually I only use the following commands to check in the change to github.

git add . //add the change in the staging area

git commit -m "commit"  //add the change to the local repository

git push //to check in the change to GitHub

Some times it is weird, I discovered that new files were check into the remote repository, the modified files still kept in the local repository.

It is better to use this command to check into the remote repository with force flag to ensure the change should be upload from local to remote repository.

git push --set-upstream origin master -f 

one dot ./ vs two ../ path in Nodejs import

it is common problem, should we use one dot or two dot in the import path.

here is the note

one dot ./ represent the current directory

two dot ../ represent the parent directory

if you have the following file structure in your project

DirOne

    -file1.js

    -file2.js

DirTwo

    -file3.js

    -file4.js

if you wan to import file1. js into file2.js

in file2.js

import file1 from "./file1.js"

if  we want to import file3.js into file2.js, since there are in two different directory, we have to reference to the parent directory then DirTwo.

we need to put this following import statement into file2.js

import file3 from "../DirTwo/file3.js" 

bodyParser had been deprecated and re-added to express.json.

 Usually we use bodyParser from body-parser library to parse the json object in the express server.

after we upgrade the express library to 4.16. we should receive the following message.

The signature '(options?: OptionsJson & OptionsText & OptionsUrlencoded): NextHandleFunction' of 'bodyParser' is deprecated.ts(6387)

index.d.ts(19, 5): The declaration was marked as deprecated here.

before we use this one to limit the JSON object size.

app.use(bodyParser.urlencoded({limit:'25mb'extended:true}));
app.use(bodyParser.json({limit:'25mb'}));

currently it directly interact with express object

app.use(express.urlencoded({limit:'25mb'extended:true}));
app.use(express.json({limit:'25mb'}));


Friday, July 16, 2021

how to access FastAPI swagger UI from local development?

 It is super cool that FastAPI did provide the Swagger UI without any configuration. after I compile and launch the backend application. then I can use the following link to access the swagger.

http://localhost:8000/docs/ 







we can perform our test within this swagger, instead of using any API Client software.

Wednesday, July 14, 2021

how to pass dockerfile argument from docker-compose file?

 It should be very convenient and dynamic, if we can set our environment variable on docker build time.

since I want to turn graphql playground on and off during the production deployment, I already use the 

NODE_ENV to control the playground feature in the .env file.

in .net file

NODE_ENV=dev

GraphQLModule.forRoot({
      playground: process.env.NODE_ENV === 'dev',
      debug: process.env.NODE_ENV === 'dev',
      autoSchemaFile: true,
    }),


we can use ARG to set a variable in the dockerfile that we can pass in during docker build run.

ARG node_env_var
ENV NODE_ENV=$node_env_var
RUN echo $node_env_var

here is the full content of Dockfile

FROM node:14 as production

ARG node_env_var
ENV NODE_ENV=$node_env_var
RUN echo $node_env_var

WORKDIR /usr/src/api

COPY package.json .
COPY yarn.lock .

RUN yarn global add @nestjs/cli

RUN yarn install --production=true

## install NIC s a computer networking utility for reading from and 
# writing to network connections using TCP or UDP.
RUN apt-get -q update && apt-get -qy install netcat

COPY . .

RUN yarn build

CMD ["sh", "-c", "yarn typeorm migration:run && yarn start:prod"]



in the Docker-compose.yml file we can set the args variable. when I run the deployment in the production environment, i can simply change the node_env_var: production

build
            contextserver
            targetproduction
            dockerfileDockerfile
            args:
                node_env_vardev

here is the docker-compse.yml file

version"3.8"

services:
    mysqldb:
        imagemysql
        environment
            - MYSQL_ROOT_PASSWORD=Mys0l@123456
            - MYSQL_DATABASE=hyrecar
        ports
            - 3306:3306
        command--default-authentication-plugin=mysql_native_password
        networks:
            - shared-network
        volumes
            - db-config:/etc/mysql
            - db-data:/var/lib/mysql
            - ./db/backup/files:/data_backup/data
       
    #acting as a proxy

    nginx:
        imagenginx:latest
        container_namenginx-prod
        volumes
            - ./nginx/nginx.conf:/etc/nginx/nginx.conf
        ports
            - 81:80
        command/bin/sh -c "nginx -g 'daemon off;'"    
        depends_on
            api-prod:
                conditionservice_healthy
            app-prod:
                conditionservice_started
        networks
            - shared-network

    api-prod:
        container_namenestjs_api_prod
        imagenestjs_api_prod:1.0.0.0
        build
            contextserver
            targetproduction
            dockerfileDockerfile
            args:
                node_env_vardev
        commandsh -c './bin/wait-for -t 0 mysqldb:3306 -- yarn start:prod'
        depends_on
            - mysqldb
        networks
            - shared-network
        ports
            - 9000:9000
        restartunless-stopped
        healthcheck:
            test: ["CMD""curl""http://api-prod:9000"]
            interval5s
            timeout3s
            retries6     
        
    app-prod:
        container_namerect_app_prod
        imagerect_app_prod:1.0.0
        build:
            contextweb
            targetproduction
            dockerfileDockerfile
        commandyarn run start:prod
        ports
            - 3000:3000
        networks
            - shared-network
        restartunless-stopped

#intialize network
networks
    shared-network:

#Initializing docker compose volumes
volumes
    db-config:
    db-data:


for development and test environment deployment.

set node_env_var: dev in docker-compose.yml 

run docker-compose build to rebuilt the container

execute docker-compose up to run all containers

in the production, we just need to change node_env_var: production

then we can run docker-compose build & docker-compose up to turn off graphql playground feature for security reason.

 Please Note you can not simply update the variable in the docker-compose yaml file and run docker-compose up since the variable is passing in at docker-compose build time, not the run time. so We have to run docker-compose build process to take the effect.



Monday, July 12, 2021

how to disable graphql in Apollo Server?

 It is very convenient to have graphql playground enable on the Apollo Server during the development.

However there will be a security issue if we have this feature enable on the production server. we must 

turn off this feature in the production environment.  we can easily turn on/off this feature on the Apollo

Server configuration setup. I create a environment variable to control this feature.

const apolloServer = new ApolloServer({
        schema: await buildSchema({
          resolvers: [UserResolvers]
        }),
        context: ({ reqres }) => ({ reqres }),
        introspection: process.env.DEV_ENV==="development",
        playground: process.env.DEV_ENV==="development",});

handy timeout function to test for loading functionality?

During the development, we will add a loading indicator to the page to notify the user that data is loading.

however, the local environment might be able to test loading indicator since the speed is too fast.

the alternative way to do so is to add a small time out function to hold the execution of data loading function. then we can check the indicator will be shown or not.

const wait = (timeout: number) => new Promise((rs) => setTimeout(rs, timeout));

then we can use it in the data loading function 

 await wait(6000);

The data loading function will be paused for 6 second. That is enough for us to see the loading indicator spinning in the page.

I recommand to add this package to your project for loading indicator.

yarn add react-spinners

import MoonLoader from "react-spinners/MoonLoader";

add this to the render section

 <MoonLoader loading size={20} />






how to fix the a component or section is not show in React on launch or refreshing the browser?

 I use React-Carousel to implement a carousel for my app. however i found something is weird. the carousel is functiong well during the run. However I refresh the browser with F5 key, the carousel disappear. here is the snippet of code for the carousel.

 return <CarContainer>

             <Carousel value={current} onChange={setCurrent} slides={
cars.map(item=><Car {...item} />)}
            plugins={[
                "clickToChange",
                {
                  resolve: slidesToShowPlugin,
                  options: {
                    numberOfSlides: 3,
                  },
                },
              ]}
              
              breakpoints={{
                640: {
                  plugins: [
                    "clickToChange",
                    {
                      resolve: slidesToShowPlugin,
                      options: {
                        numberOfSlides: 1,
                      },
                    },
                  ],
                },
                900: {
                  plugins: [
                    {
                      resolve: slidesToShowPlugin,
                      options: {
                        numberOfSlides: 2,
                      },
                    },
                  ],
                },
              }}
            /><Dots value={current} onChange={setCurrent} number={numberOfDots}/>
        </CarContainer>
the root cause of this issue is that the cars object is still null, whenn it 
render during the refresh.
slides={cars.map(item=><Car {...item} />)}
the safe way and best practice is to make sure the data is ready before the 
component rendering. since the component will not render after the data 
is ready, unless we update the cars object in the useEffect hook. 
We can either check if cars object is null return null to prevent the 
carousel render. if(!cars) return null;
or we can use the inline conditional expression wiht logical && operator.

 return cars && <CarContainer>

             <Carousel value={current} onChange={setCurrent} slides={
cars.map(item=><Car {...item} />)}
            plugins={[
                "clickToChange",
                {
                  resolve: slidesToShowPlugin,
                  options: {
                    numberOfSlides: 3,
                  },
                },
              ]}
              
              breakpoints={{
                640: {
                  plugins: [
                    "clickToChange",
                    {
                      resolve: slidesToShowPlugin,
                      options: {
                        numberOfSlides: 1,
                      },
                    },
                  ],
                },
                900: {
                  plugins: [
                    {
                      resolve: slidesToShowPlugin,
                      options: {
                        numberOfSlides: 2,
                      },
                    },
                  ],
                },
              }}
        /><Dots value={current} onChange={setCurrent} number={numberOfDots}/>
        </CarContainer>

Saturday, July 10, 2021

the guide to setup NestJS, TypeORM, MySQL,GraphQL for Backend Development

 here is a step to follow in order to setup a backend development with TypeORM, MySQL

1. install NestJS CLI

    yarn add -g @nestjs/cli

2. create a nestjs app

    nest new my-project

3. install @nestjs/typerom typreorm mysql2 (mysql 2 is much typescript friendly than mysql)

    yarn add @nestjs/typeorm typeorm mysql2 

4. create a TypeORM config JSON file to store typeorm configuation.

    touch ormconfig.json

5. paste the following into the ormconfig.json file

    {

   "type": "mysql",
   "host": "localhost",
   "port": 3306,
   "username": "test",
   "password": "test",
   "database": "test",
   "synchronize": true,
   "logging": false,
   "entities": [
      "src/entity/**/*.ts"
   ],
   "migrations": [
      "src/migration/**/*.ts"
   ],
   "subscribers": [
      "src/subscriber/**/*.ts"
   ]
}

6. add @nestjs/config package to the project so that we can use ConfigureModule module to access the configuration file.

    yarn add @nestjs/config 

7.  add a database module to the project

    touch database.module.ts

8. add the following code the database.module.ts to setup the database connection.

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Connection } from 'typeorm';

@Module({
  imports: [TypeOrmModule.forRoot()],
  exports: [TypeOrmModule],
})
export class DatabaseModule {
  constructor(connectionConnection) {
    if (connection.isConnected) {
      console.log('DB connected Successfully');
    }
  }
}

9. add DatabaseModule to the app.module.ts file    

import { Module } from '@nestjs/common';

import { ConfigModule } from '@nestjs/config';

import { AppController } from './app.controller';
import { AppService } from './app.service';
import { DatabaseModule } from './database/database.module';

@Module({
  imports: [ConfigModule.forRoot(), DatabaseModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}


10. execute yarn start to launch the project and you will see the DB connection had been established.

DB connected Successfully

[Nest] 16320  - 2021-07-10, 9:02:02 p.m.     LOG [InstanceLoader] TypeOrmCoreModule dependencies initialized +26ms

[Nest] 16320  - 2021-07-10, 9:02:02 p.m.     LOG [InstanceLoader] DatabaseModule dependencies initialized +1ms

[Nest] 16320  - 2021-07-10, 9:02:02 p.m.     LOG [RoutesResolver] AppController {/}: +5ms

[Nest] 16320  - 2021-07-10, 9:02:02 p.m.     LOG [RouterExplorer] Mapped {/, GET} route +3ms

[Nest] 16320  - 2021-07-10, 9:02:02 p.m.     LOG [NestApplication] Nest application successfully started +2ms

11. add Graphql to the project

yarn add @nestjs/graphql graphql-tools graphql apollo-server-express

you might encounter  missing package errors here, you can manually add them as following

yarn add ts-morph @apollo/gateway


12. add GraphQLModule to the app.module.ts to initialze GraphQL Module

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { GraphQLModule } from '@nestjs/graphql';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ComponentModule } from './components/comonents.module';
import { DatabaseModule } from './database/database.module';

@Module({
  imports: [
    ConfigModule.forRoot(),
    DatabaseModule,
    GraphQLModule.forRoot({
      playground: process.env.NODE_DEV === 'dev',
      debug: process.env.NODE_DEV === 'dev',
      autoSchemaFile: true,
    }),
    ComponentModule,
  ],
  controllers: [AppController],
  providers: [AppService],

})
export class AppModule {}


Further reading

NestJS Dccument

TypeORM - Amazing ORM for TypeScript and JavaScript ES7