99 lines
2.7 KiB
JavaScript

const { ApolloServer } = require('@apollo/server');
const { startStandaloneServer } = require('@apollo/server/standalone');
const { Pool } = require('pg');
require('dotenv').config();
// 1. Inisialisasi Pool PostgreSQL
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: {
rejectUnauthorized: false,
},
});
// 2. Definisi Schema GraphQL (typeDefs)
const typeDefs = `#graphql
type Category {
id: ID!
name: String!
description: String
products: [Product!]!
}
type Product {
id: ID!
title: String!
price: Float!
category_id: Int
created_by: ID
category: Category
}
type Query {
categories: [Category!]!
category(id: ID!): Category
products: [Product!]!
product(id: ID!): Product
}
`;
// 3. Definisi Resolver (Query + Nested Resolvers)
const resolvers = {
Query: {
categories: async () => {
const result = await pool.query('SELECT * FROM categories ORDER BY id ASC');
return result.rows;
},
category: async (_, { id }) => {
const result = await pool.query('SELECT * FROM categories WHERE id = $1', [id]);
return result.rows[0] || null;
},
products: async () => {
// price di-cast ke float agar cocok dengan tipe Float di GraphQL
const result = await pool.query('SELECT id, title, price::float, category_id, created_by FROM products ORDER BY id ASC');
return result.rows;
},
product: async (_, { id }) => {
const result = await pool.query('SELECT id, title, price::float, category_id, created_by FROM products WHERE id = $1', [id]);
return result.rows[0] || null;
},
},
// Resolver Relasi Category -> Products (One-to-Many)
Category: {
products: async (parent) => {
const result = await pool.query(
'SELECT id, title, price::float, category_id, created_by FROM products WHERE category_id = $1 ORDER BY id ASC',
[parent.id]
);
return result.rows;
},
},
// Resolver Relasi Product -> Category (Many-to-One)
Product: {
category: async (parent) => {
if (!parent.category_id) return null;
const result = await pool.query('SELECT * FROM categories WHERE id = $1', [parent.category_id]);
return result.rows[0] || null;
},
},
};
// 4. Inisialisasi Apollo Server
const server = new ApolloServer({
typeDefs,
resolvers,
introspection: true, // Wajib aktif untuk Apollo Sandbox publik
});
// 5. Jalankan Server
async function startServer() {
const port = process.env.PORT || 4000;
const { url } = await startStandaloneServer(server, {
listen: { port: Number(port) },
});
console.log(`Server GraphQL siap di: ${url}`);
}
startServer();