CORS on custom API endpoint
This is what I have in api.ts file
import { MiddlewareConfigFn } from "wasp/server";
import { FooBar } from "wasp/server/api"; // This type is generated by Wasp based on the
nothing seems to fix it, any ideas?
api
declaration above.
export const apiMiddleware: MiddlewareConfigFn = (config) => {
return config;
};
export const fooBar: FooBar = (req, res, context) => {
res.set("Access-Control-Allow-Origin", ""); // Example of modifying headers to override Wasp default CORS middleware.
res.json({ msg: Hello, ${context.user ? "registered user" : "stranger"}!
});
};
// export const fooBar = (req: any, res: {
// set: (arg0: string, arg1: string) => void;
// json: (arg0: { msg: string; }) => void;
// }, context: { user: any; }) => {
// console.log("Hello from fooBar!");
// console.log("User:", context.user);
// res.set("Access-Control-Allow-Origin", ""); // Example of modifying headers to override Wasp default CORS middleware.
// res.json({ msg: Hello, ${context.user ? "registered user" : "stranger"}!
});
// };
And in main.wasp
api fooBar {
fn: import { fooBar } from "@src/api",
httpRoute: (GET, "/foo/bar"),
auth: true,
middlewareConfigFn: import { apiMiddleware } from "@src/api"
}
I get CORS when hitting it for some reason, as you can see I tried using it with auth,without auth with res.set("Access-Control-Allow-Origin", "*");nothing seems to fix it, any ideas?
7 Replies
Hi @fustuk.. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
It seems like you're experiencing a common issue with CORS when trying to use custom HTTP API endpoints in Wasp. Here are a few suggestions based on the information provided in the knowledge sources:
1. Ensure CORS is enabled: APIs in Wasp are designed to be flexible and don't utilize the default middleware like Operations do. Therefore, to use these APIs on the client side, you must ensure that CORS (Cross-Origin Resource Sharing) is enabled. You can do this by defining custom middleware for your APIs in the Wasp file. source (https://wasp-lang.dev/docs/advanced/apis#making-sure-cors-works)
2. Use
apiNamespace
for CORS: It seems that the best way to handle CORS is by defining the middleware via apiNamespace
Wasp feature, instead of defining it directly on the api
. This has to do with setting CORS for the OPTION route, not just GET or POST, which is needed for CORS. source (https://github.com/wasp-lang/wasp/issues/1757)
3. Check your server-side code: There might be an error earlier in server-side code that actually is not a CORS error, but manifests as such - other errors can sometimes mask as CORS errors. It's recommended to add some console.log()s to your server code (both middleware and action) to see how far it gets on the server side before it throws an error. source (https://github.com/wasp-lang/wasp/issues/1757)
If you're still experiencing issues, it might be helpful to create a minimal example that reproduces the issue. This could be a small Wasp app that showcases the issue you're experiencing, ideally as a public repo on Github. This would allow others to run it on their machine and help troubleshoot the issue. source (https://github.com/wasp-lang/wasp/issues/1757)
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
Sorry @fustuk., I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist:
Perhaps try again in 15mins?hmm very weird if I just fetch it works, but using api.get does not, this solved it
const res = await fetch("http://localhost:3001/foo/bar");
console.log(await res.json())
// const res2 = await api.get("foo/bar");
// console.log(res2.data);
Wohooo @fustuk., you just became a Waspeteer level 1!
on a POST custom endpoint, req.body is null but I do send it in the request, why is that?
export const fooBar = (req: any, res: {
set: (arg0: string, arg1: string) => void;
json: (arg0: { msg: string; }) => void;
}, context: { user: any; }) => {
console.log("Hello from fooBar!");
console.log("User:", context.user);
console.log("Request:", req.body);
res.set("Access-Control-Allow-Origin", "");
res.json({ msg:
Hello, ${context.user ? "registered user" : "stranger"}! ${req.body.key1}
});
};
and If I add
headers: {
'Content-Type': 'application/json',
},
on the client side, I get CORS, without it it doesnt pass req.body..
export const fooBar = async (req, res: {
set: (arg0: string, arg1: string) => void;
json: (arg0: { msg: string; }) => void;
}, context: { user: any, entities: any; }) => {
const c = await context.entities.Video.count();
console.log(c)
const video = await context.entities.Video.create({ youtube: req.query.yt });
console.log(video);
res.set("Access-Control-Allow-Origin", "");
res.json({msg: Hello, ${context.user ? "registered user" : "stranger"}!
});
};
@kapa.ai how can I insert entity from a custom api endpointLet me check the knowledge base for you. One moment! :books:
----------------------
To insert an entity from a custom API endpoint in Wasp, you can use the
context.entities
object which exposes the Prisma API for each entity. In your case, you are using the Video
entity. Here's how you can create a new Video
:
In the above code, context.entities.Video.create()
is used to create a new Video
. The create()
method takes an object that should match the shape of your Video
entity. In this case, it seems like you are passing a youtube
field from the request query parameters.
Please note that the create()
method is asynchronous and returns a Promise
, so you should use await
to wait for the promise to resolve.
This is based on the Prisma's CRUD API which is exposed by the context.entities
object. source (https://wasp-lang.dev/docs/advanced/apis#using-entities-in-apis)
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
Sorry @fustuk., I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist:
Perhaps try again in 15mins?@kapa.ai okay, how do I use context.entities.video to get videos filtered by userId
Let me check the knowledge base for you. One moment! :books:
----------------------
To filter videos by
userId
using context.entities.Video
, you can use the findMany()
method provided by Prisma. Here's an example:
In the above code, context.entities.Video.findMany()
is used to fetch all Video
entities that match the provided filter. The where
clause is used to specify the filter conditions. In this case, it's filtering videos where the userId
matches the id
of the current user (context.user.id
).
Please note that the findMany()
method is asynchronous and returns a Promise
, so you should use await
to wait for the promise to resolve.
This is based on the Prisma's CRUD API which is exposed by the context.entities
object. source (https://wasp-lang.dev/docs/advanced/apis#using-entities-in-apis)
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
Sorry @fustuk., I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist:
Perhaps try again in 15mins?