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();