I am online
← Back to Articles

Create Mini Blog using Bun.js

NodejsMarch 20, 2024

To create a mini blog using Bun.js, GraphQL, TypeORM, and PostgreSQL, here is a step-by-step guide that walks you through building a simple blog with posts and categories.

Step 1: Set Up Bun.js

Ensure Bun is installed on your system. If not, you can install it:

bun install

Step 2: Create Project Directory

Set up your project directory:

mkdir mini-blog
cd mini-blog
bun init

Step 3: Install Dependencies

You’ll need the following packages:

bun add graphql typeorm pg reflect-metadata
bun add @types/node --dev

Step 4: Configure TypeORM

Set up the ormconfig.ts to connect with PostgreSQL:

import { DataSource } from 'typeorm';
import { Post } from './entities/Post';
import { Category } from './entities/Category';

export const AppDataSource = new DataSource({
  type: 'postgres',
  host: 'localhost',
  port: 5432,
  username: 'your_username',
  password: 'your_password',
  database: 'mini_blog',
  synchronize: true,
  logging: true,
  entities: [Post, Category],
  migrations: [],
  subscribers: [],
});

Step 5: Create Entities

Define the Post and Category entities using TypeORM.

Post.ts:

import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm';
import { Category } from './Category';

@Entity()
export class Post {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  title: string;

  @Column()
  content: string;

  @ManyToOne(() => Category, (category) => category.posts)
  category: Category;
}

Category.ts:

import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';
import { Post } from './Post';

@Entity()
export class Category {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @OneToMany(() => Post, (post) => post.category)
  posts: Post[];
}

Step 6: Define GraphQL Schema

Create a GraphQL schema in schema.ts:

import { buildSchema } from 'graphql';

export const schema = buildSchema(`
  type Post {
    id: ID!
    title: String!
    content: String!
    category: Category
  }

  type Category {
    id: ID!
    name: String!
    posts: [Post!]
  }

  type Query {
    getPosts: [Post!]
    getCategories: [Category!]
  }

  type Mutation {
    createPost(title: String!, content: String!, categoryId: ID!): Post
    createCategory(name: String!): Category
  }
`);

Step 7: Create Resolvers

Write the resolvers in resolvers.ts to handle GraphQL queries and mutations:

import { Post } from './entities/Post';
import { Category } from './entities/Category';
import { AppDataSource } from './ormconfig';

export const resolvers = {
  getPosts: async () => {
    return await AppDataSource.getRepository(Post).find({ relations: ['category'] });
  },
  getCategories: async () => {
    return await AppDataSource.getRepository(Category).find({ relations: ['posts'] });
  },
  createPost: async ({ title, content, categoryId }) => {
    const category = await AppDataSource.getRepository(Category).findOneBy({ id: categoryId });
    const post = new Post();
    post.title = title;
    post.content = content;
    post.category = category;
    return await AppDataSource.manager.save(post);
  },
  createCategory: async ({ name }) => {
    const category = new Category();
    category.name = name;
    return await AppDataSource.manager.save(category);
  },
};

Step 8: Create Bun Server

Create a simple server using Bun.js to handle GraphQL requests in index.ts:

import { serve } from "bun";
import { graphql } from "graphql";
import { schema } from './schema';
import { resolvers } from './resolvers';
import { AppDataSource } from './ormconfig';

AppDataSource.initialize().then(() => {
  console.log("Data Source initialized");
});

serve({
  port: 3000,
  fetch: async (req) => {
    const { query, variables } = await req.json();
    const result = await graphql({ schema, source: query, variableValues: variables, rootValue: resolvers });
    return new Response(JSON.stringify(result), {
      headers: { "Content-Type": "application/json" },
    });
  },
});

Step 9: Test the API

Start the server:

bun run index.ts

You can now test your API using a GraphQL client (e.g., Postman or GraphQL Playground):

Create a Category:

mutation {
  createCategory(name: "Tech") {
    id
    name
  }
}

Create a Post:

mutation {
  createPost(title: "First Post", content: "This is my first post.", categoryId: 1) {
    id
    title
    content
    category {
      name
    }
  }
}

Fetch Posts:

query {
  getPosts {
    id
    title
    content
    category {
      name
    }
  }
}