Next js api routing
Published: 2022-11-09 22:54:40

menghubungkan next js api ke https://www.prisma.io/

```
pnpm create next-app next_api_routes
code .
pnpm run dev
```

```
//hello.js bawaan

https://nextjs.org/docs/api-routes/introduction

export default function handler(req, res) {
  res.status(200).json({ name: 'John Doe' })
}

```
![api json bawaan next](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mvd9j848n4nikcxsg13g.png)

coba kita tambahkan beberapa data hello.js Api

```
//hello.js

// Next.js API route support: https://nextjs.org/docs/api-routes/introduction

export default function handler(req, res) {
  res.status(200).json({ 
    success : true,
    data : [
      {
        id : 1,
        username : "andiismail"
      },
      {
        id : 2,
        username : "kakak"
      },
      {
        id : 3,
        username : "aan"
      },
    ]
  })
}

```
selanjutnya kita buat folder blogs > read.js di dalam folder pages >api

```
//read.js

export default function handler (req, res){

    console.info(req)

    res.status(200).json({
        success : true
    })
}
```


![console kosong](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/en67kqr0wd6t801m5lkh.png)

tampilan command promt disisi client, kita coba menambahkan query yang masih kosong

![cmd query](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4wn4fjacd2hpl8kw62ds.png)

gambar cmd di atas query masih kosong. selanjuntnya kit akan menangkap tulisan url kedalam query, caranya menambahkan .query `console.info(req.query)`
 
tampilan console kosong
![console kosong](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mdmqemxpxpb3qaiyby0o.png)

tampilan cmd, kita bisa menangkap query dari request yang dikirim dari sisi client

![cmd](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f9q3kjm5sp0feq2e0s77.png)

menggunakan metode "GET" http. selanjutnya kita akan menangkap request query

```
//read.js

export default function handler (req, res){
    console.info(req.query)
    res.status(200).json({
        success : true,
        query : req.query
    })
}
```

![tampil succes dan request querynya](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0vhd3rrur5xiqm2dn7y0.png)

selanjutnya kita akan buat dummy array yang berisi 3 object.

```
//read.js

const dummyBlogs = [
    {
        id : 1,
        title : "Ini blog pertama saya",
        body : "Ini body pertama saya",
        banner : "https://picsum.photos/seed/1/500/300"
    },
    {
        id : 2,
        title : "Ini blog kedua saya",
        body : "Ini body kedua saya",
        banner : "https://picsum.photos/seed/2/500/300"
    },
    {
        id : 3,
        title : "Ini blog ketiga saya",
        body : "Ini body ketiga saya",
        banner : "https://picsum.photos/seed/3/500/300"
    },
]
export default function handler (req, res){
    console.info(req.query)
    res.status(200).json({
        success : true,
        // query : req.query
        data : dummyBlogs
    })
}
```

![succes dan data](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/87zns3kdimo8naxn2lso.png)

menampilkan success dan data dummyBlogs. selanjutnya kita buat create.js didalam folder blogs, status 201 untuk create artinya ada data yang dirubah disisi database

```
//create.js

export default function handler(req, res){
    res.status(201).json({
        success :true,
        message : "data berhasil disimpan..."
    })
}
```

![create](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fkg2ljo1p7m7xiocj9ne.png)

```
//create.js

export default function handler(req, res){
    //jika req method bukan post maka retur error
    if (req.method!=="POST"){
        return res.status(404).json({
            success : false,
            message : "tidak ditemukan..."
        })
    }
    res.status(201).json({
        success :true,
        message : "data berhasil disimpan..."
    })
}
```

![Image tidak ditemukan](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pjiwt6icu9h2o1wcrrgt.png)

selanjutnya kita akan melakukan fetching data untuk api yang telah kita sebelumnya di folder blogs yaitu crate.js dan read.js. ubah index.js menjadi index.jsx. hapus semua dan sisakan head main

```
//index.jsx

import Head from 'next/head'
import Image from 'next/image'
import styles from '../styles/Home.module.css'

export default function Home() {
  return (
    <div className={styles.container}>
      <Head>
        <title>Next js Api route</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <main className={styles.main}>
      </main>
    </div>
  )
}

```
untuk fetching data di next js bisa menggunakan get static props, get server side props, dan bisa melakukan hit api disisi client sama seperti di react js, kita buat state, kemudian kita buat handle function fething data, kemudian selanjutnya kita gunakan sueeffect untuk merender. yang kita gunakan get server side props.

```
//index.jsx

import Head from 'next/head'
import Image from 'next/image'
import styles from '../styles/Home.module.css'

export default function Home({data}) {
  return (
    <div className={styles.container}>
      <Head>
        <title>Next js Api route</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        {data.map((e)=>(
          <div key={e.id}>
            <h3>{e.title}</h3>
            <p>{e.body}</p>
          </div>
        ))}
      </main>
    </div>
  )
}

export async function getServerSideProps(){
  const result = await fetch("http://localhost:3000/api/blogs/read")
  const { data } = await result.json()
  return {
    props : {
      data : data //steleh membuat data kita masukkan ke Home()
    }
  }
}
```
menampilkan variabel data bisa dengan dua cara, karena data bentuknya objek terdiri dari success dan data : 

`bisa const { data } = await result.json()` atau

```
const data = await result.json()
return {
    props : {
      data : data.data
    }
  }
```

![index js](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z4p4nqfntvyfwt5iuayh.png)

selanjutnya kita akan buat dashboard.jsx di pages

```
//dashboard.jsx

export default function Dashboard() {
   
    return (
        <div className={StyleSheet.main}>
            <form className="styles.form" action="">
                <div>
                    <label htmlFor="title">judul</label>
                    <input type="text" id="title" required />
                </div>
                <div>
                    <label htmlFor="body">kontent</label>
                    <textarea type="text" id="body" required ></textarea>
                </div>
                <button type="submit">
                    submit
                </button>
            </form>
        </div>
    )
}
```

![form dashboard](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zl6kvwok4lq78nzj5l2q.png)

selanjutnya kita buat function yang menghandle form 

```
//dashboard.jsx

import styles from "../styles/Home.module.css"

export default function Dashboard() {
    const handleSubmit = (e) => {
        e.preventDefault()
        const title = e.target.title.value
        const body = e.target.body.value 

        fetch("http://localhost:3000/api/blogs/create", {
            method: "POST",
            headers: {
                "Content-Type" : "application/json"
            },
            body: JSON.stringify({ title, body })
        })
            .then(res => res.json())
            .then(data => { console.info(data) })
            .catch(err=>{console.error(err)})
    }

    return (
        <div className={styles.main}>
            <form className="styles.form" action="" onSubmit={handleSubmit}>
                <div>
                    <label htmlFor="title">judul</label>
                    <input type="text" id="title" required />
                </div>
                <div>
                    <label htmlFor="body">kontent</label>
                    <textarea type="text" id="body" required ></textarea>
                </div>
                <button type="submit">
                    submit
                </button>
            </form>
        </div>
    )
}
```

![handle form berhsil](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y3uq341p5wnvyrigsqck.png)

selanjutnya kita akan menambahkan request body di create.js

```
//create,js

export default function handler(req, res){

    //jika req method bukan post maka retur error
    if (req.method!=="POST"){
        return res.status(404).json({
            success : false,
            message : "tidak ditemukan..."
        })
    }

    res.status(201).json({
        success :true,
        message: "data berhasil disimpan...",
        body :req.body //tambahkan ini
    })
}
```

![tampilkan body dan title](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n3inuf8kf6jm0pe3dq74.png)

kita tampilkan headers di console  

```
create.js

export default function handler(req, res){

    //jika req method bukan post maka retur error
    if (req.method!=="POST"){
        return res.status(404).json({
            success : false,
            message : "tidak ditemukan..."
        })
    }

    res.status(201).json({
        success :true,
        message: "data berhasil disimpan...",
        body: req.body, //tambahkan ini
        headers : req.headers
    })
}
```

![tambahkan header](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q44ztm4yq6yj65ozlkj9.png)

![prisma web](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p8fjp3ncd2rfqbvjdb1r.png)

`pnpm install prisma
 npx prisma init
`
kita akan mengganti posgre ke db sqlite di .env

```
//.env

DATABASE_URL="file:./db.sqlite"
```

```
//schema.prisma

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}

model Blogs {
  id        Int      @id @default(autoincrement())
  title     String
  body      String
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

```
`npx prisma db push`
`npx prisma studio`

sebelumnya install prisma client, 

![Install prisma client](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w1ku23qk6xemy81ecf5h.png)

![tabel prisma yan kita buat](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iayhjgccyjkbpb0gpdtc.png)

selanjutnya kita membutuhkan sebuah connector untuk menghubungkan database kita.
di dalam prisma kita buat db.js

```
//db.js

import { PrismaClient } from "@prisma/client"

const db = new PrismaClient()
export default db
```
selanjutnya kita akan import db kedalam create.js

```
//create.js

import db from "../../../prisma/db"

export default async function handler(req, res) {

    //jika req method bukan post maka retur error
    if (req.method!=="POST"){
        return res.status(404).json({
            success : false,
            message : "tidak ditemukan..."
        })
    }

    const createBlog = await db.blogs.create({
        data : req.body
    })

    res.status(201).json({
        success :true,
        message: "data berhasil disimpan...",
        body : createBlog,
    })
}
```

```
//package.json

{
  "name": "next_api_routes",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@prisma/client": "^4.6.0",
    "next": "13.0.2",
    "prisma": "^4.6.0",
    "react": "18.2.0",
    "react-dom": "18.2.0"
  }
}
```

```
//create.js

import db from "../../../prisma/db";

export default async function handler(req, res) {
  //jika req method bukan post maka retur error
  if (req.method !== "POST") {
    return res.status(404).json({
      success: false,
      message: "tidak ditemukan...",
    });
  }

  const createBlog = await db.blogs.create({
    data: req.body,
  });

  res.status(201).json({
    success: true,
    message: "data berhasil disimpan...",
    body: createBlog,
    //body: req.body,
  });
}

```

```
//read.js

import db from "../../../prisma/db"

const dummyBlogs = [
    {
        id : 1,
        title : "Ini blog pertama saya",
        body : "Ini body pertama saya",
        banner : "https://picsum.photos/seed/1/500/300"
    },
    {
        id : 2,
        title : "Ini blog kedua saya",
        body : "Ini body kedua saya",
        banner : "https://picsum.photos/seed/2/500/300"
    },
    {
        id : 3,
        title : "Ini blog ketiga saya",
        body : "Ini body ketiga saya",
        banner : "https://picsum.photos/seed/3/500/300"
    },
]
export default async function handler (req, res){

    //console.info(req.query)
    const result = await db.blogs.findMany()
    res.status(200).json({
        success : true,
        // query : req.query
        //data : dummyBlogs
        data : result
    })
}
```
ada 2 server yang berjalan

```
pnpm run dev > localhost:3000
&& npx prisma studio > localhost:5555
```

![Image dashboard](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zc1y82bq59c1u6lvzywl.png)

![Image prisma table](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2g27h7m2p8o9dxma3p9n.png)

![Image Home](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ocj7ar29vigwl6vi797u.png)

Terimakasih.
https://github.com/andiks2018/JvalleyNext-ApiRoutingSendiri.git