W
Wasp-langβ€’8mo ago
terrence

how to add middleware for actions and querys

I see there is doc for add middleware for api, but how to add middleware for actions or querys? I dont see a tutorial for that, and tried many ways, it does not works
20 Replies
kapa.ai
kapa.aiβ€’8mo ago
Hi @terrence. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- In Wasp, you can customize middleware in three places: globally, per-api, and per-path. However, currently, there is no direct way to add middleware specifically for actions or queries. For global middleware, any changes will apply by default to all operations (query and action) and api. This is helpful if you wanted to add support for multiple domains to CORS, for example. Here is how you can modify the global middleware:
// main.wasp
app todoApp {
// ...
server: {
setupFn: import setup from "@src/serverSetup",
middlewareConfigFn: import { serverMiddlewareFn } from "@src/serverSetup"
},
}

// src/serverSetup.js
import cors from 'cors'
import { config } from 'wasp/server'

export const serverMiddlewareFn = (middlewareConfig) => {
// Example of adding extra domains to CORS.
middlewareConfig.set('cors', cors({ origin: [config.frontendUrl, '<https://example1.com',> '<https://example2.com']> }))
return middlewareConfig
}
// main.wasp
app todoApp {
// ...
server: {
setupFn: import setup from "@src/serverSetup",
middlewareConfigFn: import { serverMiddlewareFn } from "@src/serverSetup"
},
}

// src/serverSetup.js
import cors from 'cors'
import { config } from 'wasp/server'

export const serverMiddlewareFn = (middlewareConfig) => {
// Example of adding extra domains to CORS.
middlewareConfig.set('cors', cors({ origin: [config.frontendUrl, '<https://example1.com',> '<https://example2.com']> }))
return middlewareConfig
}
This will modify the middleware for all operations and APIs. Please treat modifications to global middleware with extreme care as they will affect all operations and APIs. If you are unsure, use one of the other two options. For per-api and per-path middleware, you can override middleware for a specific api route (e.g. POST /webhook/callback) or customize middleware for all methods under a given path. This is helpful for things like "complex CORS requests" which may need to apply to both OPTIONS and GET, or to apply some middleware to a set of api routes. For more information, you can refer to the Wasp middleware configuration documentation (https://wasp-lang.dev/docs/advanced/middleware-config). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @terrence, 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?
miho
mihoβ€’8mo ago
So, the bot is correct as far as that we don't support "operations" middleware. However, since operations are just POST routes, you can in theory define some path middleware that's used for /operations path. Why would you need the middleware? To have some common behaviour across the operations? 😊
terrence
terrenceOPβ€’8mo ago
I'm trying to add a feature which upload pdf and parse, extract all the contents, then display on the webpage, so I made it works with api, but now I need to save the contents to the db with target user entity, so I think it only work with actions? but I dont see a doc to describe how to add middleware with actions and query
miho
mihoβ€’8mo ago
Uploading files with actions won't be possible even if you manage to add middleware for the specific route at which the action is triggered e.g. action uploadFile will be at POST /operations/uploadFile It won't be possible because our actions API only give you the req.body and you'll need req.file to get the actual file (if you are using multer). So, the alternative problem for you is then: how to use entities inside of APIs? That's possible! If we defined our API like this:
api fileUpload {
fn: import { uploadFile } from "@src/apis",
entities: [File],
httpRoute: (POST, "/upload")
}
api fileUpload {
fn: import { uploadFile } from "@src/apis",
entities: [File],
httpRoute: (POST, "/upload")
}
I wrote my apis.ts like this:
import { MiddlewareConfigFn } from "wasp/server";
import { FileUpload } from "wasp/server/api";
import multer from "multer";

const upload = multer({ dest: "uploads/" });
export const addMiddleware: MiddlewareConfigFn = (config) => {
config.set("multer", upload.single("file"));
return config;
};

export const uploadFile: FileUpload = async (req, res, context) => {
const { File } = context.entities;
await File.create({
data: {
path: req.file!.path,
},
})

const file = req.file!;
return res.json({
fileExists: !!file,
});
};
import { MiddlewareConfigFn } from "wasp/server";
import { FileUpload } from "wasp/server/api";
import multer from "multer";

const upload = multer({ dest: "uploads/" });
export const addMiddleware: MiddlewareConfigFn = (config) => {
config.set("multer", upload.single("file"));
return config;
};

export const uploadFile: FileUpload = async (req, res, context) => {
const { File } = context.entities;
await File.create({
data: {
path: req.file!.path,
},
})

const file = req.file!;
return res.json({
fileExists: !!file,
});
};
Where I have used the third param of the API handler called context which contains entities which contains all the entities I specified in the Wasp file πŸ™‚
No description
martinsos
martinsosβ€’8mo ago
@miho and while they can use Prisma directly as you described, they can even access entities via the same system as we have for Actions/Queries, right? https://wasp-lang.dev/docs/advanced/apis#using-entities-in-apis
miho
mihoβ€’8mo ago
Oh yes! I forgot we exposed it like that πŸ€¦β€β™‚οΈ let me update the example above
martinsos
martinsosβ€’8mo ago
Ah so many cool features we have, to easy to forget them πŸ˜„
terrence
terrenceOPβ€’8mo ago
Api always getting this cors error, although it's opened already, I see you suggest in an CORs api error thread suggest to use action to solve
No description
miho
mihoβ€’8mo ago
Did you add middleware to the API? Can you share that code 😊
terrence
terrenceOPβ€’8mo ago
How to solve this CORS error problem?
miho
mihoβ€’8mo ago
Gist
Uploading files with Wasp 0.12.3
Uploading files with Wasp 0.12.3. GitHub Gist: instantly share code, notes, and snippets.
terrence
terrenceOPβ€’8mo ago
No description
No description
No description
MEE6
MEE6β€’8mo ago
Wohooo @terrence, you just became a Waspeteer level 2!
miho
mihoβ€’8mo ago
This should be fine πŸ€— the code I shared on the link works for me
terrence
terrenceOPβ€’8mo ago
The thing is it was working in the beginning, but the next day I did not add anything, this error just shows up
miho
mihoβ€’8mo ago
Are actions and queries still working for you?
terrence
terrenceOPβ€’8mo ago
Authentication still works I can login logout etc It’s just when I call this api, it get this cors error
miho
mihoβ€’8mo ago
aw yes, now I see, you need to define a apiNamespace with a middleware and not set the middleware with the api Check this link out. The reason is that: because of the way Express works, the middleware you specify in api gets only applied to the POST method (or whichever method you put in the api). For CORS to work properly, you need the middleware on the OPTIONS method as well! And apiNamespace sets the middleware for all HTTP methods (GET, POST ... including OPTIONS).
terrence
terrenceOPβ€’8mo ago
Thank you, I will take a look
martinsos
martinsosβ€’8mo ago
We have an issue to improve this experience: https://github.com/wasp-lang/wasp/issues/1303
Want results from more Discord servers?
Add your server