<?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: Dwi purnomo</title>
    <description>The latest articles on DEV Community by Dwi purnomo (@dwipr).</description>
    <link>https://dev.to/dwipr</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%2F4738%2Fc00d0911-fe6d-401a-8456-c01f5646de79.jpg</url>
      <title>DEV Community: Dwi purnomo</title>
      <link>https://dev.to/dwipr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dwipr"/>
    <language>en</language>
    <item>
      <title>TypeORM Connection in NestJS</title>
      <dc:creator>Dwi purnomo</dc:creator>
      <pubDate>Wed, 18 Sep 2019 09:55:59 +0000</pubDate>
      <link>https://dev.to/dwipr/typeorm-connection-in-nestjs-5f4a</link>
      <guid>https://dev.to/dwipr/typeorm-connection-in-nestjs-5f4a</guid>
      <description>&lt;p&gt;&lt;em&gt;Post in Indonesian, &lt;a href="https://antaraksi.com/tutorial-nestjs-untuk-backend-rest-api-bag-2-koneksi-ke-basis-data-mysql/"&gt;TypeORM Connection in NestJS&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A software can have a function to save data to database. To save data, usually it uses software such as MySQL, SQLite, or MongoDB with communication using ORM (Object-relational Mapping).&lt;/p&gt;

&lt;p&gt;NestJS has three ORM support namely TypeORM, Sequelize and Mongoose. In this tutorial I will only use TypeORM. The advantages of TypeORM in NestJS over other ORMs are that TypeORM and Nest Framework are both built using Typescript language so that they can be well integrated.&lt;/p&gt;

&lt;p&gt;Following are the steps to connect a MySQL database to a Nest Framework application using TypeORM:&lt;/p&gt;

&lt;h2&gt;
  
  
  Install the dependencies.
&lt;/h2&gt;

&lt;p&gt;To begin, we will install the TypeORM dependencies. We will use MySQL as the database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install --save @nestjs/typeorm typeorm mysql
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Create a database in MySQL.
&lt;/h2&gt;

&lt;p&gt;We will create a database now that will be connected to our Nest application in MySQL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE DATABASE hello;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Make a Connection Configuration.
&lt;/h2&gt;

&lt;p&gt;Now, we will make a connection configuration in &lt;code&gt;AppModule&lt;/code&gt; to connect to our MySQL &lt;code&gt;hello&lt;/code&gt; database. Import and use the &lt;code&gt;TypeOrmModule&lt;/code&gt; from Nest here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'hello',
      entities: [__dirname + '/**/*.entity{.ts,.js}']
    }),
  ],
})
export class AppModule {}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Done, our application can be connected to our &lt;code&gt;hello&lt;/code&gt; database now. The username and password configuration can be different, adjust it to fit yours.&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional: TypeORM CLI.
&lt;/h2&gt;

&lt;p&gt;TypeORM has CLI capabilities that can be used to create entities, migrations, etc. If we make a connection configuration like no. 3 above, we cannot use TypeORM's CLI.&lt;/p&gt;

&lt;p&gt;As an alternative, we can make a json-based configuration.&lt;/p&gt;

&lt;p&gt;Create a file called &lt;code&gt;ormconfig.json&lt;/code&gt; at the root of this project, fill in the configuration with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "mysql",
  "host": "localhost",
  "port": 3306,
  "username": "root",
  "password": "root",
  "database": "hello",
  "entities": ["src/**/*.entity{.ts,.js}"],
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once again, The username and password configuration can be different, adjust it to fit yours.&lt;/p&gt;

&lt;p&gt;Now, delete the connection configuration inside &lt;code&gt;TypeOrmModule.forRoot()&lt;/code&gt; and make it only calls the &lt;code&gt;TypeOrmModule.forRoot()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [TypeOrmModule.forRoot()],
})
export class AppModule {}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Done, now we can use the TypeORM CLI because our application now read the connection configuration from &lt;code&gt;ormconfig.json&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>typeorm</category>
      <category>orm</category>
    </item>
    <item>
      <title>Example REST API with Express.js, Mongoose and Babel</title>
      <dc:creator>Dwi purnomo</dc:creator>
      <pubDate>Sun, 30 Jun 2019 02:12:19 +0000</pubDate>
      <link>https://dev.to/dwipr/example-rest-api-with-express-js-mongoose-and-babel-2483</link>
      <guid>https://dev.to/dwipr/example-rest-api-with-express-js-mongoose-and-babel-2483</guid>
      <description>&lt;p&gt;&lt;em&gt;Read on &lt;a href="https://antaraksi.com/example-rest-api-that-uses-express-js-mongoose-and-babel/"&gt;my blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This article will discuss an example of making a REST API using Express.js, Mongoose and Babel. The resource or endpoint created is only users. We will only make a simple user registration method. We will use a repository pattern.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install the package
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  yarn add express mongoose mongod
  yarn add --dev @babel/cli @babel/core @babel/node @babel/preset-env nodemon
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create folder structure
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.
├── package.json
├── src
│   ├── controllers
│   │   └── UserController.js
│   ├── index.js
│   ├── models
│   │   ├── repositories
│   │   │   └── UserRepository.js
│   │   └── User.js
│   └── routes
│       ├── index.js
│       └── users.js
└── yarn.lock

5 directories, 8 files
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;User Model &lt;code&gt;User.js&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import mongoose from 'mongoose';

const { Schema } = mongoose;

const schema = new Schema({
  email: {
    type: String
  },
  password: {
    type: String
  }
});

const User = mongoose.model('User', schema);
export default User;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;User Repository &lt;code&gt;UserRepository.js&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create a &lt;code&gt;repositories&lt;/code&gt; folder in the models folder, then create &lt;code&gt;UserRepository.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import User from '../User';

class UserRepository {

  constructor(model) {
    this.model = model;
  }

  create(object) {
    return this.model.create(object);
  }
}

export default new UserRepository(User);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then create &lt;code&gt;UserController.js&lt;/code&gt; in the &lt;code&gt;controllers&lt;/code&gt; folder.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User Controller &lt;code&gt;UserController.js&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import UserRepository from '../models/repositories/UserRepository';

function createUser(req, res) {
  const user = req.body;

  UserRepository.create(user)
    .then((newUser) =&amp;gt; {
      res.json(newUser);
    }).catch((errors) =&amp;gt; {
      res.status(500).json({
        errors,
      });
    });
}

export default { createUser };
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After that we list the routes in the &lt;code&gt;routes&lt;/code&gt; folder as &lt;code&gt;users.js&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User Route &lt;code&gt;users.js&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import express from 'express';
import UserController from '../controllers/UserController';

const router = express.Router();

router.post('/', UserController.createUser);

export default router;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And index.js on routes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import express from 'express';
import users from './users';

const router = express.Router();

router.use(express.json());

router.use('/users', users);

export default router;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Finally we create &lt;code&gt;index.js&lt;/code&gt; in the &lt;code&gt;src&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server &lt;code&gt;index.js&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import express from 'express';
import mongoose from 'mongoose';

import routes from './routes';

mongoose.Promise = global.Promise;

const app = express();

app.use('/', routes);

mongoose.connect('mongodb://localhost:27017/db')
  .then(() =&amp;gt; {
    console.log('mongodb started.');
    app.listen(8000, () =&amp;gt; {
      console.log('Server started on 8000');
    });
  }).catch(() =&amp;gt; {
    console.log('Mongodb connection failed.');
  })
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Command to run the server
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nodemon -w src -x "babel-node src --presets @babel/env"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can add it to &lt;code&gt;npm-scripts&lt;/code&gt; in &lt;code&gt;package.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "exercise",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "express": "^4.17.1",
    "mongodb": "^3.2.7",
    "mongoose": "^5.6.2",
    "nodemon": "^1.19.1"
  },
  "devDependencies": {
    "@babel/cli": "^7.4.4",
    "@babel/core": "^7.4.5",
    "@babel/node": "^7.4.5",
    "@babel/preset-env": "^7.4.5"
  },
  "scripts": {
    "start": "nodemon -w src -x \"babel-node src --presets @babel/env\""
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That was practicing express.js, mongoose and babel using a simple REST API. The entire code can be seen at &lt;a href="https://github.com/yoiso/exercise-express"&gt;https://github.com/yoiso/exercise-express&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>express</category>
      <category>mongoose</category>
      <category>babel</category>
    </item>
    <item>
      <title>How to Create Role based Authorization Middleware with Casbin and Nest.js</title>
      <dc:creator>Dwi purnomo</dc:creator>
      <pubDate>Sat, 11 May 2019 13:53:21 +0000</pubDate>
      <link>https://dev.to/dwipr/how-to-create-role-based-authorization-middleware-with-casbin-and-nest-js-52gm</link>
      <guid>https://dev.to/dwipr/how-to-create-role-based-authorization-middleware-with-casbin-and-nest-js-52gm</guid>
      <description>&lt;p&gt;&lt;em&gt;Read on &lt;a href="https://antaraksi.com/casbin-midleware-for-nest-js-with-restful-policy/"&gt;my site&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In this article, i will show you how to create Role based authorization middleware with Casbin and Nest.js. Casbin is an authorization library that supports access control models like ACL, RBAC, ABAC for Golang, Java, PHP and Node.js, but in this article, we will use the Node.js.&lt;/p&gt;

&lt;p&gt;Nest is a progressive Node.js framework for building efficient, reliable and scalable server-side applications. It uses Typescript language and support multiple core server like Express, Koa or Fastify.&lt;/p&gt;

&lt;p&gt;If you prefer to watch in video format:&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/mWlPNrCgVdE"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Here is the text format:&lt;/p&gt;

&lt;p&gt;Before we create the project, install Nest first.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -g @nestjs/cli
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And then we create a project with the Nest cli&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nest new theproject
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then, open the project directory and install the Casbin&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd theproject
npm install --save casbin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After this, we enter the coding phase.&lt;/p&gt;

&lt;p&gt;First, create the policy configuration for Casbin.&lt;/p&gt;

&lt;p&gt;In the src, create a directory named casbin_conf.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd src
mkdir casbin_conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Create model.conf and policy.csv in the casbin_conf&lt;/p&gt;

&lt;p&gt;File model.conf:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = r.sub == p.sub &amp;amp;&amp;amp; keyMatch(r.obj, p.obj) &amp;amp;&amp;amp; (r.act == p.act || p.act == "*")
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;File policy.csv:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;p, admin, /*, GET
p, notadmin, /, POST
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the policy we define two rules, one is for user who have admin role and the other is for user who have notadmin role.&lt;/p&gt;

&lt;p&gt;After that, we create the Nest middleware.&lt;/p&gt;

&lt;p&gt;Create a middleware named authorization.middleware.ts in src&lt;/p&gt;

&lt;p&gt;File authorization.middleware.ts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Enforcer } from 'casbin';

export class BasicAuthorizer {
    private req: any;
    private enforcer: any;

    constructor(req, enforcer) {
        this.req = req;
        this.enforcer = enforcer;
    }

    getUserRole() {
        const { user } = this.req;
        const { role } = user;
        return role;
    }

    checkPermission() {
        const { req, enforcer } = this;
        const { originalUrl: path, method } = req;
        const userRole = this.getUserRole();
        return enforcer.enforce(userRole, path, method);
    }
}

// the authorizer middleware
export function authz(newEnforcer: () =&amp;gt; Promise&amp;lt;Enforcer&amp;gt;) {
    return async (req, res, next) =&amp;gt; {
        const enforcer = await newEnforcer();

        // user sample
        req.user = {role: 'admin'};

        if(!(enforcer instanceof Enforcer)) {
            res.status(500).json({500: 'Invalid enforcer'});
            return;
        }

        const authorizer = new BasicAuthorizer(req, enforcer);
        if(!authorizer.checkPermission()) {
            res.status(403).json({403: 'Forbidden'});
            return;
        }

        next();
    }
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's the authorization middleware logic, Casbin will help checking the permission.&lt;/p&gt;

&lt;p&gt;Then we integrate the middleware in Nest project bootstrap.&lt;/p&gt;

&lt;p&gt;Find the maint.ts, integrate the authorization middleware in the app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

import { newEnforcer } from 'casbin';
import { authz } from './authorization.middleware';

import { join } from 'path';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // authorization middleware that is registered as global middleware
  app.use(authz(async() =&amp;gt; {
      const enforcer = await newEnforcer(join(__dirname, 'casbin_conf/model.conf'), join(__dirname, 'casbin_conf/policy.csv'));
      return enforcer;
  }));
  await app.listen(3000);
}
bootstrap();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That is the authorization middleware that is registered as global middleware in the app.&lt;/p&gt;

&lt;p&gt;Boot up the project to test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run start:dev
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you want to experiment, modify the sample user in the authz, remove that if you want make it into production.&lt;/p&gt;

&lt;p&gt;Here is the project &lt;a href="https://github.com/x1yy/theproject"&gt;repository&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>rbac</category>
      <category>casbin</category>
      <category>nest</category>
      <category>security</category>
    </item>
    <item>
      <title>Hi, I'm Dwi purnomo</title>
      <dc:creator>Dwi purnomo</dc:creator>
      <pubDate>Sat, 03 Jun 2017 16:42:25 +0000</pubDate>
      <link>https://dev.to/dwipr/hi-im-dwi-purnomo</link>
      <guid>https://dev.to/dwipr/hi-im-dwi-purnomo</guid>
      <description>&lt;p&gt;You can find me on Gitlab as &lt;a href="https://gitlab.com/brspd" rel="noopener noreferrer"&gt;brspd&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I live in Yogyakarta, Indonesia.&lt;/p&gt;

&lt;p&gt;I mostly program in these languages: php.&lt;/p&gt;

&lt;p&gt;I am currently learning more about REST API.&lt;/p&gt;

&lt;p&gt;Nice to meet you.&lt;/p&gt;

</description>
      <category>introduction</category>
    </item>
  </channel>
</rss>
