Merhaba arkadaşlar, bugün başımı çok ağrıtan bir sorunu, yani GraphQL API'mi farklı bir domain'den gelen isteklere açarken yaşadığım CORS sıkıntılarını ve Apollo Server 4'te bunu nasıl düzgün çözdüğümü anlatacağım. Özellikle preflight (OPTIONS) istekleri GraphQL endpoint'inde takılıp kalıyordu ve kafayı yemiştim. İşte benim bulduğum en temiz çözüm.
Karşılaştığım Sorun
Apollo Server 4'e geçtiğimde, eski `cors` paketini ve `applyMiddleware` yaklaşımını kullanmak artık mümkün değildi. Frontend'den gelen her `POST` isteği öncesi atılan `OPTIONS` isteği, 404 veya 405 hatası alıyordu. Tarayıcı, "CORS policy" diye bağırıyordu. Sorun şuydu: Apollo Server, varsayılan olarak sadece `POST` metodunu kabul ediyor ve `OPTIONS` isteklerini işlemiyordu.
Apollo Server 4 ve Express Middleware Çözümü
Çözüm, Apollo Server'ı bir Express uygulamasına entegre edip, CORS middleware'ini Apollo'nun kendi `expressMiddleware` fonksiyonundan ÖNCE eklemekti. Böylece `OPTIONS` istekleri Apollo'ya ulaşmadan önce yakalanıp doğru header'lar ile yanıtlanabiliyordu.
İşte kurulumun nasıl yapıldığı:
Ekstra Güvenlik ve Özel Durumlar
Eğer sadece GraphQL endpoint'inizde CORS'a izin vermek istiyorsanız (ki önerilir), middleware'i global yerine sadece `/graphql` yoluna da ekleyebilirsiniz. Ayrıca, karmaşık preflight istekleri için `cors` paketinin opsiyonlarını kullanmak çok işe yarıyor.
Sonuç olarak, anahtar nokta, CORS middleware'ini Apollo Server'ın işleyeceği yoldan önce konumlandırmak. Bu sayede `OPTIONS` isteği Apollo'ya ulaşmadan, CORS middleware'i tarafından uygun header'lar ile yanıtlanıyor ve ardından asıl `POST` isteği sorunsuzca işleniyor.
Siz Apollo Server veya başka bir GraphQL sunucusunda (Hasura, Yoga) benzer CORS sorunları yaşadınız mı? Sizin kullandığınız farklı bir yöntem veya daha şık bir çözümünüz var mı? Yorumlarda paylaşırsanız çok sevinirim!
Apollo Server 4'e geçtiğimde, eski `cors` paketini ve `applyMiddleware` yaklaşımını kullanmak artık mümkün değildi. Frontend'den gelen her `POST` isteği öncesi atılan `OPTIONS` isteği, 404 veya 405 hatası alıyordu. Tarayıcı, "CORS policy" diye bağırıyordu. Sorun şuydu: Apollo Server, varsayılan olarak sadece `POST` metodunu kabul ediyor ve `OPTIONS` isteklerini işlemiyordu.
Çözüm, Apollo Server'ı bir Express uygulamasına entegre edip, CORS middleware'ini Apollo'nun kendi `expressMiddleware` fonksiyonundan ÖNCE eklemekti. Böylece `OPTIONS` istekleri Apollo'ya ulaşmadan önce yakalanıp doğru header'lar ile yanıtlanabiliyordu.
İşte kurulumun nasıl yapıldığı:
JavaScript:
import express from 'express';
import { ApolloServer } from '@apollo/server';
import { expressMiddleware } from '@apollo/server/express4';
import cors from 'cors';
const app = express();
const PORT = process.env.PORT || 4000;
// 1. CORS Middleware'i Express app'e GLOBAL olarak ekliyoruz.
// Bu, TÜM isteklerden (OPTIONS dahil) önce çalışır.
app.use(cors({
origin: ['https://benimguvenlifrontend.com', 'http://localhost:3000'],
credentials: true, // Eğer cookie/authorization header kullanacaksanız
}));
// 2. Apollo Server'ı oluşturuyoruz.
const server = new ApolloServer({
typeDefs,
resolvers,
});
// 3. Server'ı başlatıyoruz.
await server.start();
// 4. GraphQL yoluna Apollo middleware'ini ekliyoruz.
// DİKKAT: Bu satır, CORS middleware'inden SONRA gelmeli.
app.use('/graphql', express.json(), expressMiddleware(server));
// 5. Express sunucusunu dinlemeye başlıyoruz.
app.listen(PORT, () => {
console.log(`🚀 Server ready at http://localhost:${PORT}/graphql`);
});
Eğer sadece GraphQL endpoint'inizde CORS'a izin vermek istiyorsanız (ki önerilir), middleware'i global yerine sadece `/graphql` yoluna da ekleyebilirsiniz. Ayrıca, karmaşık preflight istekleri için `cors` paketinin opsiyonlarını kullanmak çok işe yarıyor.
JavaScript:
// SADECE /graphql yoluna özel CORS ayarı
import { cors } from 'cors';
const corsOptions = {
origin: function (origin, callback) {
const allowedOrigins = ['https://benimguvenlifrontend.com'];
if (!origin || allowedOrigins.indexOf(origin) !== -1) {
callback(null, true);
} else {
callback(new Error('CORS politikası ile engellendi'));
}
},
methods: ['POST', 'OPTIONS'], // Sadece gerekli metodlar
allowedHeaders: ['Content-Type', 'Authorization'],
};
app.use('/graphql', cors(corsOptions), express.json(), expressMiddleware(server));
Sonuç olarak, anahtar nokta, CORS middleware'ini Apollo Server'ın işleyeceği yoldan önce konumlandırmak. Bu sayede `OPTIONS` isteği Apollo'ya ulaşmadan, CORS middleware'i tarafından uygun header'lar ile yanıtlanıyor ve ardından asıl `POST` isteği sorunsuzca işleniyor.
Siz Apollo Server veya başka bir GraphQL sunucusunda (Hasura, Yoga) benzer CORS sorunları yaşadınız mı? Sizin kullandığınız farklı bir yöntem veya daha şık bir çözümünüz var mı? Yorumlarda paylaşırsanız çok sevinirim!