"no service set in context" Unable to test API Gateway with SQS integration in localstack

Been digging all day trying to get some kind of lead on why the API Gateway w/ SQS integration doesn’t work in localstack but is fine on AWS. Doesn’t seem like it’s a paid feature or anything but the logs are giving me nothing to go on.

It’s either a bad ARN that I need to conditionally set for localstack (annoying)
Or I’m not calling the right invoke URL and it’s just giving me a 200 back dumbly regardless.

The invoke URL I’m trying to test with for localstack is something like this.

Terraform Invoke URL
https://uoxt3znba5.execute-api.us-east-1.amazonaws.com/v1

localstack
http://localhost:4566/restapis/8zvsgsigfk/v1/streams/<streamname>/push

I’m getting the API Gateway ID using

awslocal apigateway get-rest-apis

But when I hit localstack all I get is an empty 200 back and these logs.

2023-06-01T19:07:19.015 DEBUG --- [   asgi_gw_2] l.aws.handlers.service     : no service set in context, skipping request parsing
2023-06-01T19:07:19.016  INFO --- [   asgi_gw_2] localstack.request.http    : POST /restapis/uoxt3znba5/v1/streams/test/push => 200

The verbose logs just have that when I hit the localhost.

My localstack looks like this.

services:
  localstack:
    image: localstack/localstack:latest
    ports:
      - '4566-4599:4566-4599'
      - '8080:8080'
    environment:
      - SERVICES=apigateway,sqs,ssm
      - DEBUG=1
      - DATA_DIR=/tmp/localstack/data
      - DOCKER_HOST=unix://var/run/docker.sock
    volumes:
      - './.localstack:/tmp/localstack'
      - '/var/run/docker.sock:/var/run/docker.sock'

My terraform for the AWS integration looks like this.


resource "aws_api_gateway_integration" "integration" {
  rest_api_id = aws_api_gateway_rest_api.streaming_ingest_api.id
  resource_id = aws_api_gateway_resource.push_resource.id
  http_method = aws_api_gateway_method.method.http_method

  type                    = "AWS"
  integration_http_method = "POST"
  uri                     = "arn:aws:apigateway:${var.region}:sqs:path//${var.sqs_queue_name}"
  credentials             = var.aws_integration_execution_role_arn

  request_parameters = {
    "integration.request.header.Content-Type" = "'application/x-www-form-urlencoded'"
  }

  request_templates = {
    "application/json"                  = <<EOF
Action=SendMessage&MessageBody=$input.body&MessageAttribute.1.Name=stream&MessageAttribute.1.Value.StringValue=$input.params('stream')&MessageAttribute.1.Value.DataType=String
EOF
    "application/x-www-form-urlencoded" = <<EOF
Action=SendMessage&MessageBody=$input.body&MessageAttribute.1.Name=stream&MessageAttribute.1.Value.StringValue=$input.params('stream')&MessageAttribute.1.Value.DataType=String
EOF
  }
}

Any idea what is wrong here? This all works correctly in a real AWS environment but I can’t seem to figure out why localstack doesn’t work the same way.

Hi @russ,

Please have a look at our samples that could be helpful with the configuration of the terraform template.
Repository: localstack/localstack-terraform-samples

For more details about SQS, please visit Simple Queue Service (SQS) | Docs (localstack.cloud).

Hello @russ,

The URL format for invoking API Gateway with LocalStack are the following:

  • http://<apiId>.execute-api.localhost.localstack.cloud:4566/<stageId>/<path>
  • or, alternatively: http://localhost:4566/restapis/<apiId>/<stageId>/_user_request_/<path>

You can read more about the URL format here in our documentation: Amazon API Gateway | Docs