Feat: Resolver
This commit is contained in:
parent
3b458298e0
commit
e86e5d3bbd
@ -8,10 +8,10 @@ const pool = new Pool({
|
||||
ssl: {
|
||||
rejectUnauthorized: false,
|
||||
},
|
||||
max: 1, // Batasi 1 koneksi per instance serverless
|
||||
max: 1,
|
||||
});
|
||||
|
||||
// 2. Definisi Schema GraphQL (typeDefs)
|
||||
// 2. Definisi Schema GraphQL
|
||||
const typeDefs = `#graphql
|
||||
type Category {
|
||||
id: ID!
|
||||
@ -37,7 +37,26 @@ const typeDefs = `#graphql
|
||||
}
|
||||
`;
|
||||
|
||||
// 3. Definisi Resolver (Query + Nested Resolvers)
|
||||
// 3. Plugin Apollo untuk menyuntikkan log counter ke response extensions
|
||||
const metricsPlugin = {
|
||||
async requestDidStart() {
|
||||
return {
|
||||
async willSendResponse({ response, contextValue }) {
|
||||
if (response.body.kind === 'single') {
|
||||
response.body.singleResult.extensions = {
|
||||
...response.body.singleResult.extensions,
|
||||
nPlusOneMetrics: {
|
||||
totalCalls: contextValue.metrics.categoryProductsCalls,
|
||||
resolverLogs: contextValue.metrics.callLogs,
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
// 4. Definisi Resolver
|
||||
const resolvers = {
|
||||
Query: {
|
||||
categories: async () => {
|
||||
@ -65,7 +84,16 @@ const resolvers = {
|
||||
|
||||
// Resolver Relasi Category -> Products (One-to-Many)
|
||||
Category: {
|
||||
products: async (parent) => {
|
||||
products: async (parent, _, contextValue) => {
|
||||
// Increment counter di context request saat ini
|
||||
contextValue.metrics.categoryProductsCalls += 1;
|
||||
const currentCall = contextValue.metrics.categoryProductsCalls;
|
||||
|
||||
// Simpan log urutan pemanggilan ke array context
|
||||
contextValue.metrics.callLogs.push(
|
||||
`[resolver counter] Category.products dipanggil ${currentCall} kali (category_id=${parent.id})`
|
||||
);
|
||||
|
||||
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]
|
||||
@ -84,17 +112,26 @@ const resolvers = {
|
||||
},
|
||||
};
|
||||
|
||||
// 4. Inisialisasi Apollo Server
|
||||
// 5. Inisialisasi Apollo Server dengan Plugin
|
||||
const server = new ApolloServer({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
introspection: true,
|
||||
csrfPrevention: false, // Mematikan proteksi CSRF agar request dari browser Sandbox tidak dicegat
|
||||
csrfPrevention: false,
|
||||
plugins: [metricsPlugin],
|
||||
});
|
||||
|
||||
const apolloHandler = startServerAndCreateNextHandler(server);
|
||||
// 6. Inisialisasi Handler dengan Context Per-Request
|
||||
const apolloHandler = startServerAndCreateNextHandler(server, {
|
||||
context: async () => ({
|
||||
metrics: {
|
||||
categoryProductsCalls: 0,
|
||||
callLogs: [],
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
// 5. Handler CORS untuk Apollo Studio dan Embedded Sandbox
|
||||
// 7. Handler CORS dan Serverless Entrypoint
|
||||
module.exports = async function handler(req, res) {
|
||||
const allowedOrigins = new Set([
|
||||
'https://studio.apollographql.com',
|
||||
@ -113,7 +150,6 @@ module.exports = async function handler(req, res) {
|
||||
'Content-Type, Authorization, apollo-require-preflight, x-apollo-operation-name'
|
||||
);
|
||||
|
||||
// Respons langsung untuk preflight OPTIONS request
|
||||
if (req.method === 'OPTIONS') {
|
||||
res.status(200).end();
|
||||
return;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user