NodeJs AdonisJS Nedir? AdonisJS Framework Kullanımı ve RESTful API Yapımı

Node.js ile yeni başlayan veya ileride kullanabileceğiniz bir çerçeve keşfetmek isteyen biriyseniz, tüm eğitimi takip etmenizi ve ayrıca AdonisJS topluluğunun bir parçası olmanızı tavsiye ederim.

AdonisJS nedir?

AdonisJs Node.js için tam özellikli bir web framework’üdür. Node.js Framework, büyük ölçüde geliştirici ergonomisine, kararlılığına ve hıza odaklanmıştır. Verimli, güvenilir ve ölçeklenebilir sunucu tarafı uygulamalar oluşturabilirsiniz.

Neden AdonisJS?

Aklınızdaki ilk soru bu olabilir. “Neden AdonisJS’yi denemeliyim?” Neyse ki, bu soruyu cevaplamak benim için yeterince kolay, çünkü AdonisJS, web sunucularınızı Node.js’de yazmak için farklı bir paradigma öneriyor. Paradigmayı tamamen beğenmeniz veya beğenmemeniz mümkündür, ancak çerçevenin kendisi, varlığı konusunda herhangi bir kafa karışıklığına neden olmayacak kadar benzersizdir.

Node.js’de her zaman tanık olduğum popüler yaklaşım, Express, Koa veya Fastify gibi mikro çerçevelerle başlamak ve ardından üzerine bir şeyler inşa etmektir. İstek gövdesini ayrıştırmak, formları doğrulamak gibi temel şeyler bile paket yönetiminden ayrı ayrı çekilmesi gerekir ve AdonisJS bunun tam tersidir .

Felsefi olarak AdonisJS, Laravel, Ruby on Rails veya Django’nun yaklaşımını izler. Bir web sunucusu oluşturmak için temel özelliklerin hemen hemen hepsinin yerleşik olduğu ve paketleri manuel olarak tek tek yapılandırılmasına gerek kalmamaktadır.

  • Request body’sinin parse edilmesi
  • Form verilerini doğrulama
  • Dosya yüklemeleri
  • Framework boyunca günlük kaydı
  • Çerezler + oturum yönetimi
  • Doğrulama
  • SQL ORM
  • Şablon motoru
  • E-posta gönderme desteği

ve çok daha fazlası zaten AdonisJS’e entegre halde, böylece projelerinize başlayıp projelerinizi birleştirmek için zaman harcamazsınız.

Uygulamalarınızı hızla geliştirmenin faydalarının yanı sıra. AdonisJS gibi tam özellikli bir çerçeve kullanmanın birkaç avantajı daha var.

  • Çerçevenin tüm paketlerindeki API tutarlıdır ve benzer adlandırma ve kod kurallarını izler. Buna karşılık, üzerinizde daha az bilişsel yük var.
  • Çerçeve, uygulamanız hakkında zaten çok şey bildiğinden, geliştirme deneyiminizi daha da iyileştirmek için özel araçlar sunabilir. AdonisJS REPL , bunun harika bir örneğidir.

Sistemsel Gereksinimler
Adonis
MySQL
Node
Postman

AdonisJS Kurulumu

Öncelikle AdonisJs’i global olarak makinamıza yüklüyoruz. Terminalimizi açıp aşağıdaki kod bloğunu çalıştırıyoruz.

npm install -global @adonisjs/cli

Terminalimizden Adonis projesi oluşturuyoruz.

adonis new Adonis-RestFull-Api --api-only

Uygulamanın çalıştığını test etmek amacı ile Terminalimizde uygulamanın dizinine gidip uygulamamızı ayağa kaldırıyoruz.

cd Adonis-RestFull-Api
adonis serve --dev

Postman üzerinden 127.0.0.1:3333 adresine get isteği yaptığımızda bizi aşağıdaki sayfanın karşılaması gerekmekte.

Bu eğitimimizde küçük bir Todo uygulaması yapacağız.

Veritabanı Bağlantısı

Uygulamamızın dizininde .env dosyasını açarak aşağıdaki kısımları kendi veritabanımıza göre şekillendiriyoruz.

HOST=127.0.0.1
PORT=3333
NODE_ENV=development
APP_NAME=AdonisJs
APP_URL=http://${HOST}:${PORT}
CACHE_VIEWS=false

APP_KEY=u5hTNMceBjWpRUhZ8zHLKU77tALLHJoo

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=root
DB_PASSWORD=
DB_DATABASE=Adonis-RestFull-Api

HASH_DRIVER=bcrypt

DB_CONNECTION — -> Veritabanı Biz bu projede mysql kullanacağız
 DB_HOST → Veritabanı adresi biz localhost’da çalıştığımız için 127.0.0.1 olarak bırakmaktayız.
DB_PORT → Veritabanı portunuz. Mysql varsayılan olarak 3306 portunda çalışır.
 DB_USER → Veritabanı Kullanıcı Adınız.
 DB_PASSWORD → Veritabanı şifreniz yazılır.
DB_DATABASE → Veritabanızın adı
APP_KEY →Kesinlikle uygulama anahtarı eklemeyi unutmayın.

Uygulamamıza npm’den mysql modülümüzü dahil ediyoruz.

npm install -save mysql

Uygulamamıza Todos Model ve Controller’ını oluşturuyoruz.

adonis make:model Todos -mc

database\migrations\xxxxxxxxxx_todos_schema.js dosyasını açıyoruz. Propertylerimizi oluşturuyoruz.

'use strict'

/** @type {import('@adonisjs/lucid/src/Schema')} */
const Schema = use('Schema')

class TodosSchema extends Schema {
  up() {
    this.create('todos', (table) => {
      table.increments()
      table.integer('user_id', 11).unsigned().references('id').inTable('users')
      table.string('title')
      table.string('body')
      table.boolean('done')
      table.timestamps()
    })
  }

  down() {
    this.drop('todos')
  }
}

module.exports = TodosSchema

app/Models/User.js dosyasını açıyoruz. User Modeli ile bağlantısını yazıyoruz. Todos ile bağlantısını oluşturuyoruz.

'use strict'

/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
const Model = use('Model')

/** @type {import('@adonisjs/framework/src/Hash')} */
const Hash = use('Hash')

class User extends Model {
  todos() {
    return this.hasMany('App/Models/Todo')
    }
  static boot () {
    super.boot()

    /**
     * A hook to hash the user password before saving
     * it to the database.
     */
    this.addHook('beforeSave', async (userInstance) => {
      if (userInstance.dirty.password) {
        userInstance.password = await Hash.make(userInstance.password)
      }
    })
  }

  /**
   * A relationship on tokens is required for auth to
   * work. Since features like `refreshTokens` or
   * `rememberToken` will be saved inside the
   * tokens table.
   *
   * @method tokens
   *
   * @return {Object}
   */
  tokens () {
    return this.hasMany('App/Models/Token')
  }
}

module.exports = User

Migration yaparak database’mizi oluşturuyoruz.

adonis migration:run

CRUD Controllerin oluşturulması

app\Controllers\Http\TodoController.js dosyasını açıyoruz. User Modeli ile bağlantısını yazıyoruz. Todos ile bağlantısını oluşturuyoruz.

'use strict'
const Todo = use('App/Models/Todo');
const User = use('App/Models/User');
/** @typedef {import('@adonisjs/framework/src/Request')} Request */
/** @typedef {import('@adonisjs/framework/src/Response')} Response */
/** @typedef {import('@adonisjs/framework/src/View')} View */

/**
 * Resourceful controller for interacting with todos
 */
class TodoController {
  //User'a Ait Todoların Gösterimi
  async all({ request, response, view }) {
    let todos = await User.query().with('todos').fetch()
    return response.json(todos)
  }


  /**
   * Show a list of all todos.
   * GET todos
   *
   * @param {object} ctx
   * @param {Request} ctx.request
   * @param {Response} ctx.response
   * @param {View} ctx.view
   */
  //Tüm Todoların Gösterimi
  async index({ request, response, view }) {
    let todos = await Todo.query().fetch()
    return response.json(todos)
  }

  /**
   * Render a form to be used for creating a new todo.
   * GET todos/create
   *
   * @param {object} ctx
   * @param {Request} ctx.request
   * @param {Response} ctx.response
   * @param {View} ctx.view
   */
  async create({ request, response, view }) {
  }

  /**
   * Create/save a new todo.
   * POST todos
   *
   * @param {object} ctx
   * @param {Request} ctx.request
   * @param {Response} ctx.response
   */
  async store({ request, response }) {
    const user_id = request.input('user_id')
    const title = request.input('title')
    const body = request.input('body')
    const done = request.input('done')
    const todo = new Todo()
    todo.user_id = user_id
    todo.title = title
    todo.body = body
    todo.done = done
    await todo.save()
    return response.json(todo)
  }

  /**
   * Display a single todo.
   * GET todos/:id
   *
   * @param {object} ctx
   * @param {Request} ctx.request
   * @param {Response} ctx.response
   * @param {View} ctx.view
   */
  async show({ params, request, response, view }) {
  }

  /**
   * Render a form to update an existing todo.
   * GET todos/:id/edit
   *
   * @param {object} ctx
   * @param {Request} ctx.request
   * @param {Response} ctx.response
   * @param {View} ctx.view
   */
  async edit({ params, request, response, view }) {
  }

  /**
   * Update todo details.
   * PUT or PATCH todos/:id
   *
   * @param {object} ctx
   * @param {Request} ctx.request
   * @param {Response} ctx.response
   */
  //Todo Güncelleme
  async update({ params, request, response }) {
    const user_id = request.input('user_id')
    const title = request.input('title')
    const body = request.input('body')
    const done = request.input('done')
    let todo = await Todo.find(params.id)
    todo.user_id = user_id
    todo.title = title
    todo.body = body
    todo.done = done
    await todo.save()
    return response.json(todo)
  }

  /**
   * Delete a todo with id.
   * DELETE todos/:id
   *
   * @param {object} ctx
   * @param {Request} ctx.request
   * @param {Response} ctx.response
   */
  //Todo Silme
  async destroy({ params, request, response }) {

    const todo = await Todo.find(params.id)

    await todo.delete()

    return response.json({ message: 'Todo deleted!' })
  }
}

module.exports = TodoController

Route’un Oluşturulması

start/routes.js dosyasının içerisine methodlar eklenir.

'use strict'

const Route = use('Route')

Route.get('/', () => {
  return { greeting: 'Hello world in JSON' }
})

Route.get('/api/all', 'TodoController.all')
Route.get('/api/todos', 'TodoController.index')
Route.post('/api/todos', 'TodoController.store')
Route.put('/api/todos/:id', 'TodoController.update')
Route.delete('/api/todos/:id', 'TodoController.destroy')

Kodlarımızı şimdi test edebiliriz. Terminalimizden aşağıdaki kod bloğunu çalıştırarak uygulamamızı test edelim.

adonis serve --dev

POSTMAN İSTEKLERİ

JWT Kimlik Doğrulama

Bazı Endpoint’leri güvenlik gereği public yapmayız. Bu bakımdan genelde kullanılan JWT (JSON Web Tokens) entegre edeceğiz.

config/auth.js dosyamızı açarak authenticator property’sini değerinin jwt olduğunu göreceksiniz.

module.exports = {
authenticator: 'jwt',

Sonrasında sayfanın biraz aşağısında bulunan JWT bloğuna gelerek Hangi modeli kullanacağımızı ve bu model üzerinde hangi property’lerin unique değer ve şifre olacağını tanımlıyoruz.

  jwt: {
    serializer: 'lucid',
    model: 'App/Models/User',
    scheme: 'jwt',
    uid: 'email',
    password: 'password',
    options: {
      secret: Env.get('APP_KEY')
    }
  },

Sonrasında Terminal üzerinden Token alınacak Controller’ımızı oluşturuyoruz.

adonis make:controller --type http AuthController

app\Controllers\Http\AuthController.js dosyamızı açarak kayıt ve login methodlarımızı yazıyoruz.https://hakanguzel.com/media/06188a55a7ae29a92748345b6ebb1b3e

start/routes.js sayfamızı açarak methodlarımızı tanımlıyoruz.

Route.post(‘/auth/register’, ‘AuthController.register’)
Route.post(‘/auth/login’, ‘AuthController.login’)

Daha öncesinden oluşturduğumuz Endpointlere JWT Middleware’lerimizi tanımlıyoruz.

'use strict'
const User = use('App/Models/User');

class AuthController {
  async register({ request, auth, response }) {
    const username = request.input("username")
    const email = request.input("email")
    const password = request.input("password")
    let user = new User()
    user.username = username
    user.email = email
    user.password = password
    await user.save()
    let userdetail = await User.findBy('email', email)
    let accessToken = await auth.generate(userdetail)
    return response.json({ "user": user, "access_token": accessToken })
  }

  async login({ request, auth, response }) {
    const email = request.input("email")
    const password = request.input("password");
    try {
      if (await auth.attempt(email, password)) {
        let user = await User.findBy('email', email)
        let accessToken = await auth.generate(user)
        return response.json({ "user": user, "access_token": accessToken })
      }
    }
    catch (e) {
      return response.json({ message: 'User not found!' })
    }
  }
}

module.exports = AuthController

POSTMAN İSTEKLERİ

Github Repository Gözat

Bu eğitimde Adonis ile RestApi uygulaması oluşturduk. Ayrıca oturum açma ve oturum doğrlama için JWT’i entegre ettik. Bir sonraki eğitim serisinde görüşmek üzere. Eğitimdeki eksiklikler veya anlatılmayan kısımlar için lütfen yorumlarınızı eksik etmeyiniz.

You may also like...