Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does Netlify Lambda support sub-directory ? #90

Closed
medmin opened this issue Dec 27, 2018 · 15 comments
Closed

Does Netlify Lambda support sub-directory ? #90

medmin opened this issue Dec 27, 2018 · 15 comments
Labels

Comments

@medmin
Copy link

medmin commented Dec 27, 2018

Hi,

I tried to use a sub-directory, such as ./netlify/functions/hello/world.js, and I expect the url would be localhost:9000/hello/world.

But I failed and I found nothing in the docs related to this issue.

So, I'd like to confirm that whether or not the Netlify lambda function supports such feature ? Thanks.

@swyxio
Copy link
Contributor

swyxio commented Dec 27, 2018

confirmed, your functions need to be top level js (or ts or mjs) files. this is consistent with real deployed netlify functions behavior.

pr for docs or warnings welcome!

@swyxio swyxio closed this as completed Dec 27, 2018
@medmin
Copy link
Author

medmin commented Dec 30, 2018

Currently, I use a hack , i.e., set a redirect rule in netlify.toml, and the js file is indeed a the top-level file.

[[redirects]]
  from = "/hello/world"
  to = "/.netlify/functions/hello-world"
  status = 200
  force = true

But it's a hack after all.

I prefer that the source code directory structure would be ./netlify/functions/hello/world.js and the corresponding url would be /hello/world.

Does netlify lambda support such feature ? How do I make it work ?

That's my question. And I have searched a lot and got no example, no doc or any other references.

And I would love to submit a pr to the docs, which would include a demo.

@medmin
Copy link
Author

medmin commented Dec 30, 2018

Hey, I made it!

I set up a file named net.js and a directory net/lify.js, and the code looks like:

let lify = require('./net/lify');

exports.handler = function (event, context, callback) {
    let subPath = event.path.split('/')[2];
    switch (subPath) {
        case 'lify':
            lify(event, context, callback)
            break;
        default:
            callback('404 Path Not Found!');
    }
}

I don't need a redirect rule in the netlify.toml and it's not a hack anymore and it works well.

It's still not that kind elegant solution I expect though.

It seems the Netlify Lambda uses the express framework to find the path and module. I am not familiar with it. So,....

@swyxio
Copy link
Contributor

swyxio commented Dec 31, 2018

yeah. i'm glad you figured it out.

remember that in the end we're still only locally emulating whatever is being done in the real Netlify Functions. so if they dont support subdirectories than we dont either.

@medmin
Copy link
Author

medmin commented Jan 3, 2019

Right.

Thanks for reply.

@medmin
Copy link
Author

medmin commented Jan 3, 2019

By the way, how do I add something to the docs ? I cannot find the doc repo and there is no button in the doc page to let me "Edit" or something.

@swyxio
Copy link
Contributor

swyxio commented Jan 3, 2019

the Netlify docs are unfortunately not open source. you can just ping netlify.com/support with your suggestions.

the netlify-lambda docs however... just a README on this repo

@connor11528
Copy link

@sw-yx in the tutorial you place a lambda folder within src (src/lambda)

Based on this issue should the folder be in the root for a Gatsby project?

@swyxio
Copy link
Contributor

swyxio commented Apr 24, 2019

@connor11528 you can place the lambda folder where-ever you want. this issue is for putting yet another folder inside that folder and expecting that to be reflected in the URL for the function. netlify functions dont work like that unfortunately.

@AWolf81
Copy link

AWolf81 commented Jun 7, 2019

@medmin Good idea, I also like to structure my lambdas in subdirectories.

Here's how I've added it so I can put my lambdas in a subdir - so I can use it with .netlify/function/net/lify. Pretty similar to your code but more generic.

File net.js in src/lambdas

export function handler(event, context, callback) {
  // Get the command from path (skip first as it is an empty string)
  const [, dirName, commandStr] = event.path.split("/");

  // Load the script
  try {
    const command = require(`./${dirName}/${commandStr}`);
    return command.handler(event, context, callback);
  } catch (e) {
    return callback(null, {
      headers: {
        "content-type": "application/json"
      },
      statusCode: 404,
      body: JSON.stringify({ msg: "Command not found" })
    });
  }
}

And inside src/lambda/net I'm adding the lify.js script:

export function handler(event, context, callback) {
  return callback(null, { ...});
}

A more real world example would be .netlify/functions/blog/read-all to real all blog entries.

Not hacky but there is probably a better/easier solution to this.

@swyxio swyxio reopened this Jun 8, 2019
@david-j-davis
Copy link

david-j-davis commented Aug 5, 2019

@connor11528 you can place the lambda folder where-ever you want. this issue is for putting yet another folder inside that folder and expecting that to be reflected in the URL for the function. netlify functions dont work like that unfortunately.

I have deployed my Gatsby site with functions and lambda output at the root of the directory, and my project fails to build with this error: No netlify.toml found. This is needed to configure the function settings.

Full log: https://paste.lucko.me/0mKlBEUqgy

My netlify.toml:

[build]
  base = "web/"
  command = "yarn build"
  publish = "web/public"
  functions = "./lambda"

My build command in package.json in the src/ dir I've intended for it to build from the parent directory:
"build:microservices": "netlify-lambda build /microservices",

I don't get how on the one hand it says it's building the functions, and then in the other says it can't find netlify.toml file...

@david-j-davis
Copy link

Follow up, I seemed to have solved my issue with two netlify.toml files ¯_(ツ)_/¯. Seems ridiculous, but I need one at the root of my project, and it's a Gatsby monorepo. So my frontend is in /web/src, and the root netlify.toml tells where my base path to the frontend is. Then in my web directory I have another netlify.toml that contains only my functions command, by which I am building my lambda functions at the root of my project. So obviously I need one file to tell netlify where the base is, and another one in my web directory to tell it to publish the functions in the parent directory...lol

@swyxio
Copy link
Contributor

swyxio commented Aug 5, 2019

yeah this is the standard advice for monorepos. maybe not ideal but also not super hard to do. we could always document it better.

@stale
Copy link

stale bot commented Oct 4, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Oct 4, 2019
@swyxio swyxio closed this as completed Oct 4, 2019
@step135
Copy link

step135 commented Jan 28, 2020

Putting a .js file to the subfolder of functions doesn't work for me and it is mentioned many times as solution how to read local html or pdf template. What to do to achieve it?

fs.readdir(path.resolve(__dirname, 'index.html'), function (err, f) {}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants