aws-sam-cli: start-api automatic reload does not appear to be doing anything

Hi folks,

I’m running the following command: sam local start-api

I’m running the above command inside of a directory that I created using the sam --init command. So, it’s a directory with a template.yaml file in it, and an actual node.js lamba function project folder.

The console output from sam says that I do not need to restart the CLI for changes to take affect, but modifying my code does not appear to cause any sort of automatic reload.

Do I have to do anything specific to allow this to auto reload? I’m running Windows 10.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 4
  • Comments: 18 (3 by maintainers)

Most upvoted comments

@jfuss

Forgive my ignorance and inexperience, but what is the value of sam build? Not what does it do, but why does it exist? I’d much prefer to have hot recompilation of my code during sam local start-api. In order to get any new code changes once I’ve already built a system, I have to kill the locally started api, build, then restart the local api. Why not just either (1) ignore the build directory from local start-api and integrate the build step into sam deploy? Or, automatically call sam build during the running start-api?

I can’t think of any reason I’d want to have edited source code in my source tree with a running sam local start-api pointed at a prior version of the source build. That current running server would be what I’m testing against for the source code I’m actively editing and writing. Having two separate sources of truth feels terrible to me.

SO, what am I missing? There must be a good reason you’ve chosen to provide this separation of commands. You’ve written above “…but it is working as intended”. I don’t think anyone doubts it works as intended, what I’m (and others likely are) curious about is why you intend it to work this way?

What is the workflow that requires this behavior?

Thanks.

when I run sam local start-api I get this output

You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template

Which suggests that automatic reloading is the intended behavior

@felixhageloh Yes but that ‘auto reloading’ is not ‘auto building’. The reloading in this is describing that you can update the contents of the CodeUri and see the changes without restarting the api. With the introduction of sam build, this notion changed slightly.

If you are using build, what this is saying is you can build the function without needing to restart. This is because build generates a template that is used behind the scenes that points to a build location. The confusion comes from, you as a customer only interact with the non-built function/template while the invoke can (if using build) interact with the generated built template. Maybe a rewording is in order here to make the expectation better but it is working as intended.

I create https://github.com/awslabs/aws-sam-cli/issues/921 to track the work for ‘auto building’ through sam build --watch.

Note: That output was from the pre-sam build stage.

--watch option appears to be removed from sam build making this even more cumbersome.

$ sam build --watch
Usage: sam build [OPTIONS] [FUNCTION_IDENTIFIER]
Try 'sam build --help' for help.

Error: no such option: --watch
$ sam --version
SAM CLI, version 1.15.0

I also came across this recently, hoping to get hot reload type functionality to make local development with the AWS Serverless services easier.

I’ve seen some other work arounds on other aws-sam-cli Github issues saying an option is to move your dependencies into a Lambda layer, or to develop against the .aws-sam build artefacts and copy back over to the actual code directory once done… both of which just seems cumbersome compared to our current build process using CDK (CDK handles bundling of dependencies from requirements.txt, similar to how sam build does I guess)

Even though this is a super old issue I thought I’d comment incase it’s of use to someone else.

I came up with this semi hack to get sam build to run on python file changes changes, this could be changed to suit other languages as needed.

  1. Install fswatch (This is cross platform, but the below command wont’t work on windows)
  2. fswatch -r -0 $(find <lambda directory path> -type f '(' -name "requirements.txt" -o -name "*.py" ')') | xargs -0 -n 1 -I {} sh -c 'sam build -t <template file location>

where: <lambda directory path> is the directory that contains the code (or code directories) for your Lambda function/s that are used behind API Gateway’ <template file location> is the sam template.yaml or the CDK stack json output ie cdk.out/APIStack.json

Note - the above command will run continually if your sam build command outputs .aws-sam into the <lambda directory path>, caught me when I initially pointed it at the root of my repo!

I’m using find over the built in file/dir inclusions and exclusions available in fswatch as I already had it handy in another script.

This at least reduces the time spent trying to figure out why your code changes aren’t being reflected when calling the local SAM API endpoint, because you simply forgot to run sam build 😁 .

For what it’s worth, it seems this is the first link for the phrase aws sam hot reloading not working in Google. I would have also expected the code to recompile and automatically reload.

Ahahaha! This was the exact same Google Search I just did and landed here. Yes, I agree, this message is overly confusing. I also weren’t sure why my project wasn’t hot reloading. After reading this, seems like sam just can’t do this just yet. Sad.

For local development I remove the .aws-sam build folder:

"start:local": "rm -r .aws-sam & tsc -w && sam local start-api"

I do watch for typescript compilation during hot-reloading.

To answer your question @ryancole, sam local start-api looks for changes in the .aws-sam folder IF it exists, if not, then it looks for changes in the root directory of your project.

If your project uses Golang, you can work with air to solve this problem.

.air.toml

[build]
  cmd = "sam build"
  # Do nothing with the build
  bin = "/usr/bin/true"
  include_ext = ["go"]

Makefile

start:
	(air &) && (sam local start-api &)

stop:
	ps | grep -e "[a]ir" -e "[s]am local start-api" | awk '{print $$1}' | xargs -I @ kill -9 @

@jthomerson

The confusion is that sam local start-api will always pull from the .aws-sam folder IF it exists. If you remove that folder you really do have hot-reloading, i.e. any saved code changes will be reflected in the lambda WITHOUT having to call start-api again.

This was confusing though, and I can’t remember if the documentation mentions this.

Fascinating. Thanks for the tip @alex-nishikawa! I still think that message in the SAM start-api output should be more clear about this, but at least now I learned 😁