refactor: migrate to nextjs serverless handler for vercel
This commit is contained in:
parent
4dc4a1f716
commit
6edf45b5f4
1008
package-lock.json
generated
1008
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
11
package.json
11
package.json
@ -4,8 +4,9 @@
|
|||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"dev": "next dev",
|
||||||
"start": "node index.js"
|
"build": "next build",
|
||||||
|
"start": "next start"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "",
|
||||||
@ -13,9 +14,13 @@
|
|||||||
"type": "commonjs",
|
"type": "commonjs",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apollo/server": "^5.5.1",
|
"@apollo/server": "^5.5.1",
|
||||||
|
"@as-integrations/next": "^4.1.0",
|
||||||
"cors": "^2.8.6",
|
"cors": "^2.8.6",
|
||||||
"dotenv": "^17.4.2",
|
"dotenv": "^17.4.2",
|
||||||
"graphql": "^16.14.2",
|
"graphql": "^16.14.2",
|
||||||
"pg": "^8.23.0"
|
"next": "^16.3.4",
|
||||||
|
"pg": "^8.23.0",
|
||||||
|
"react": "^19.2.8",
|
||||||
|
"react-dom": "^19.2.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
96
pages/api/graphql.js
Normal file
96
pages/api/graphql.js
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
const { ApolloServer } = require('@apollo/server');
|
||||||
|
const { startServerAndCreateNextHandler } = require('@as-integrations/next');
|
||||||
|
const { Pool } = require('pg');
|
||||||
|
|
||||||
|
const pool = new Pool({
|
||||||
|
connectionString: process.env.DATABASE_URL,
|
||||||
|
ssl: {
|
||||||
|
rejectUnauthorized: false,
|
||||||
|
},
|
||||||
|
max: 1, // Menjaga batas koneksi pada lingkungan serverless
|
||||||
|
});
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
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 () => {
|
||||||
|
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;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
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;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
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;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const server = new ApolloServer({
|
||||||
|
typeDefs,
|
||||||
|
resolvers,
|
||||||
|
introspection: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const apolloHandler = startServerAndCreateNextHandler(server);
|
||||||
|
|
||||||
|
// Wrapper untuk menangani CORS Apollo Studio Sandbox
|
||||||
|
module.exports = async function handler(req, res) {
|
||||||
|
res.setHeader('Access-Control-Allow-Credentials', 'true');
|
||||||
|
res.setHeader('Access-Control-Allow-Origin', 'https://studio.apollographql.com');
|
||||||
|
res.setHeader('Access-Control-Allow-Methods', 'GET,OPTIONS,POST');
|
||||||
|
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
||||||
|
|
||||||
|
if (req.method === 'OPTIONS') {
|
||||||
|
res.status(200).end();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return apolloHandler(req, res);
|
||||||
|
};
|
||||||
Loading…
x
Reference in New Issue
Block a user