NextJS API routes are missing from Vercel's build outputs when folder contains index.js/ts - deployment

I'm using NextJS /api routes and deploying to Vercel.
It seems that wherever I have an index.ts file located within the /api folder structure, Vercel will replace the contents of its containing folder (including /api itself) with a single file. All of the sibling route files will be ignored.
Oddly enough, the folder that contains the index file will remain--but without contents.
Ex:
/api/index.ts
/api/mock1/index.ts
/api/mock1/mock1-endpoint.ts
/api/mock2/index.ts
/api/mock2/mock2-endpoint.ts
This will produce an output of:
/api // empty folder
λ api
Note: you'll have to deploy this code to see the output in Vercel's dashboard
Reproducible code: https://github.com/angusryer/missing-lambdas-vercel-nextjs
Deployed example: https://missing-lambdas-vercel-nextjs.vercel.app/
The api routes are visible as seen in the 'source' tab of the production deployment:
But they are not available in the 'output' tab:
Does anyone know why this happens and ways to get around it?

Related

Google CDN Connection to CDN create nosuch Key Errors

i uploaded images to google storage bucket and i am no trying to set the CDN using the load balancer to work.
Storage Status :
Bucket Permissions : Storage Object Viewer - Reader assign to allUsers ,
Storage Legacy Bucket Reader assign To allUsers
File Status :
Share Public is set and there is a public link
Load Balancer:
Set to path /creatives/* on the host name
but i always get this msg:
<Error>
<Code>NoSuchKey</Code>
<Message>The specified key does not exist.</Message>
</Error>
what i notice is as soon as i build the path of /creatives/* there is another path build /* direct to the backend service of the auto scale group
am i missing here any settings?
So as i discovered Google CDN + Google http Load balancer works different from other CDN.
with a regular CDN you can direct the origin to you bucket HTTP address and work on the / structure.
for example :
Google CDN Bucket URL:
googleapi.storage.com/my-bucket
Folder structure:
/1/1.jpg
Normal CDN origin will be pointing to googleapi.storage.com/my-bucket
and you will get a new service endpoint for the CDN like:
my-bucket.fastly.cdonservice.com
and this call will work:
my-bucket.fastly.cdonservice.com/1/1.jpg
but on google cloud what you are setting up is a path that is connected to the CDN service that you created on the backend part.
So this is the big difference, lets assume that you created this path rule.
host: www.googlecdnnonexplainedfeautres.com
path: /images/*
service: yourbackendservice (connected to the bucket you want to cache)
so you might assume this should work:
www.googlecdnnonexplainedfeautres.com/images/1/1.jpg.
but NO ..
after digging the logs you will find a 404 on the bucket because google will go and search this path on the bucket:
googleapi.storage.com/my-bucket/images/1/1.jpg.
wait , where did the images came ? i thought its a hook. no google take this as a static website root ( the thing you can check on and off on S3) so here its mandatory.
so how this should work ?
modify the folder structure to be like this :
Google CDN Bucket URL:
googleapi.storage.com/my-bucket
Folder structure:
images/1/1.jpg
and now you are good.
This link should work now :
www.googlecdnnonexplainedfeautres.com/images/1/1.jpg.
so before you commit a bucket to be used as CDN source for google just add another top folder that match with the path you set on the LB.
and of course .. permissions , allUsers , read and etc..
EnjoY!
You can use URL Rewrites to solve this problem.
This may not have existed back in 2017 but there's an option at least as of 2021.
Explanation:
The lb's default behavior is to pass the entire path after the host to Cloud Storage. This may seem incorrect, but it's a sane default (How is the load balancer supposed to know what part of the path you want to include or exclude?).
I was facing the same issue.
I connected mydomain.com/static/* to my cloud storage bucket static-assets.
Upon visiting mydomain.com/static/static-asset.jpg the load balancer would request cloud storage for an object with key static-assets/**static**/static-asset.jpg.
Since the object's actual key is static-assets/static-asset.jpg, this would return a NoSuchKey response.
The fix was the rewrite the path prefix of /static to /.
One way to configure this is through the Cloud Console Load Balancer UI--we can add an advanced path rule to rewrite the prefix.
Please note:
Important: The rewrite is prepended to the path as is. Full path
rewrites are not supported. HTTP(S) Load Balancing only implements
path prefix rewrites. For example, you can rewrite:
host.name/path1/resource1 to host.name/path2/resource1. You cannot
rewrite host.name/path1/resource1 to host.name/path1/resource2.
Read about URL Rewrites here.

Context routing for two different apps

I deploy two different apps to CF and I want to be able to use the context path routing for those two apps
e.g.
lets say I've two apps that deployed and I was able to consume it with the following URL.
1. app1.domain.com
2. app2.domain.com
Now I want somehow to use the context path routing of CF
to be able to use this apps like following
1. something.domain.com/app1
2. something.domain.com/app2
My question are:
I missing the "something", what should I put in the apps manifest to be able to use it like above ?
How should I define the routes in the mainfest.yml file?
what should I put in the path?
Example will be very helpful
https://www.cloudfoundry.org/context-path-routing/
Lucky that I recently prepared a blog post and a tutorial on context path routing. Here is a sample manifest.yml taken from the tutorial that shows two apps with different routes on the same domain:
# This manifest deploys two applications.
#
# Both use the same host and domain name as defined
# by their respective route(s) property. The first app
# uses the root path, the second the "sub" and
# "lower" paths.
applications:
# The Python app starts here
- name: yourname-myapp
memory: 256M
command: python myapp.py
routes:
- route: yourname-myapp.mybluemix.net
path: ./top/
# The Node.js app starts here
- name: yourname-myapp-node
routes:
- route: yourname-myapp.mybluemix.net/lower
- route: yourname-myapp.mybluemix.net/sub
path: ./lower/
You can even define multiple routes for a single app, all in a single manifest file. The routes property is the place for the routing information. Note that the path points to the source code for the app (if done this way) and that you need a recent version of cf CLI to deploy it. See the tutorial for more information and additional links.
You can also find a good example in the map route documentation per below
https://docs.cloudfoundry.org/devguide/deploy-apps/routes-domains.html#map-route

Google PHP AppEngine - Deployment Issue with PHP file not being uploaded

I have a very simple PHP app that allows a User to enter names of Cities or Zip-codes into a search box, and the User gets auto-complete suggestions based on data stored in my Google CloudSQL server.
index.html - Renders a simple search box where users can enter search keys and they get auto-complete suggestions. Accomplished via Twitter's typeahead.js library (jQuery plugin).
city.php - PHP file that acts as a translation layer. Receives request from the browser and initiates connection to my Google CloudSQL server where I have a simple database with some city and zipcode data. Returns the data back to the browser as an array.
This works on my local Mac OS X Apache server. I am trying to get this setup to work on Google PHP AppEngine. I created an app.yaml file that looks like this:
runtime: php55
api_version: 2
threadsafe: true
handlers:
- url: /
static_files: index.html
upload: index.html
- url: /(.*)
static_files: www/\1
upload: (.*)
- url: /(.+\.php)$
script: \1
This is where I run into an issue. When I run gcloud app deploy from my local folder (which houses index.html, city.php, and app.yaml), I get the following message in the logs.
Some files were skipped. Pass `--verbosity=info` to see which ones.
You may also view the gcloud log file, found at
[/Users/arjunshah/.config/gcloud/logs/2016.11.13/12.31.04.137587.log].
When I run gcloud app deploy with log verbosity, I see the following:
INFO: Could not find any remote repositories associated with [/Users/arjunshah/Documents/autocomplete]. Cloud diagnostic tools may not be able to display the correct source code for this deployment.
File upload done.
INFO: Manifest: [{'app.yaml': {'sourceUrl': 'https://storage.googleapis.com/staging.ashah-146101.appspot.com/abbe3c7fc03eb43497686990488c54e2ae0533ea', 'sha1Sum': 'abbe3c7fc03eb43497686990488c54e2ae0533ea'}, 'index.html': {'sourceUrl': 'https://storage.googleapis.com/staging.ashah-146101.appspot.com/1865620cc55de1902c2a9636df601f532cb2657a', 'sha1Sum': '1865620cc55de1902c2a9636df601f532cb2657a'}, 'city.php': {'sourceUrl': 'https://storage.googleapis.com/staging.ashah-146101.appspot.com/64999cc8da06416a54be99c43e6e017aa0c1d01a', 'sha1Sum': '64999cc8da06416a54be99c43e6e017aa0c1d01a'}}]
Updating service [default]...
INFO: Previous default version [ashah-146101/default/20161113t122802] is an automatically scaled standard environment app, so not stopping it.
The index.html page loads fine, but when I try to enter names of cities (that I know are in the database), I see the following error in the Google Browser Inspect Element console.
Failed to load resource: https://ashah-146101.appspot.com/city.php?query=P the server responded with a status of 404 ()
Please help!

Setting source for a script

I'm a bit confused as to how setting a source works for a script inside an HTML file.
Whenever I use a script, I set the source to something along the lines of:
http://localhost:8080/module_name/module.js
However, when I go through the directory of my server, the location is actually something along the lines of:
modules/module_version2.0/module_name/module.js
How is the client accessing the source file when portions of the directory are emitted?
I think what is throwing you off is the configuration and root of the web-server/website versus the file system of the server.
The URL being read by your browser/client will lead the browser/client to the web-server located at localhost:8080 and the web-server will supply the browser/client with information from that website's root directory for any files/pages that are referenced within the html being used via the tags.
The method of configuring this direction/reference to the root or the document tree of the web-server, varies based on OS and web server setup, but is usually held in a files like httpd.conf; which is the file for Apache.
These configuration files can also have different file locations and aliases setup to create relative paths: i.e. you could have pointers for different locations within the web-server's document tree.
The path example from your server is coming from the perspective of a user account logged in to a machine using some method of exploring the systems local file structure. As such the root directory of that system is the lowest location in the file structure and therefore will show the full path of all the files and directories on that machine.
Where as the web-server/website's root directory in most likely located further away from the systems root.
Hope this helps.

Static website in Google Cloud - how to set mainpage (when index.html is in a different folder)

I just joined. I created a bucket for my static website. The index.html (or mainpage per google terminology) is in a different folder in the same bucket. I set my index.html as the page to show up automatically (www.example.com)
I get the website on my browser if i type exact http url including my file name - IT WORKS. But, if i type the domain name alone on the browser, i get the following error:
<Error>
<Code>NoSuchKey</Code>
<Message>The specified key does not exist.</Message>
</Error>
I did setup my MainPage on the bucket options. HEre is my gsutil web get.
{"mainPageSuffix": "gs://www.example.co/NewHome/index.html"}
But index.html does not show up when i type only example.co in the browser. Any suggestions???
Found the answer the path is relative to home (bucket).
So this works
{"mainPageSuffix": "NewHome/index.html"}.
In case the developers of the Google-cloud for web are listening to this...
Even though the system picks up the index.html in a different folder, the images, jss etc are not pickedup. The current working directly still remains the home directory. (In the web case this could be relaxed to change the CWD based on where the mainpage suffix is pointing to. (just an opinion).