Fork me on GitHub
Ben Hammond00:01:01

Hi. I am trying to use apigatewaymanagementapi to post data to a websocket When I run this from the repl

(-> (aws/client {:api :apigatewaymanagementapi
                 :region :eu-west-2
                 :endpoint-override {:hostname ""
                                     :stage "dev"
                                     :protocol :https}
    (aws/invoke {:op :PostToConnection
                 :request {:ConnectionId "L9YKjdwtrPEAbMA="
                           :Data "helloworld"}}))
{:message "Invalid connectionId: L9YKjdwtrPEAbMA=L9YKjdwtrPEAbMA=",
 :cognitect.anomalies/category :cognitect.anomalies/incorrect}
and I see from the meta that somehow the ConnectionId `L9YKjdwtrPEAbMA=` gets turned in to `L9YKjdwtrPEAbMA=L9YKjdwtrPEAbMA=`
(meta *1)
{:http-request {:request-method :post,
                :scheme :https,
                :server-port 443,
                :uri "/@connections/L9YKjdwtrPEAbMA%3DL9YKjdwtrPEAbMA=",
                :headers {"x-amz-date" "20220114T233422Z",
                          "x-amz-target" ".PostToConnection",
                          "content-type" "application/x-amz-json-1.1",
                          "host" "",
                          "authorization" "***"
                          :body #object[java.nio.HeapByteBuffer
                              "java.nio.HeapByteBuffer[pos=0 lim=10 cap=10]"],
                :server-name ""},
 :http-response {:status 400,
                 :headers {"x-amz-apigw-id" "***=",
                           "connection" "keep-alive",
                           "x-amzn-requestid" "4af13b6f-5010-4f5e-b8cf-59eff9f856ba",
                           "x-amzn-errortype" "BadRequestException",
                           "content-length" "68",
                           "date" "Fri, 14 Jan 2022 23:34:22 GMT",
                           "content-type" "application/json"},
                 :body #object[
I am running {:mvn/version "770.2.568.0"}
am I somehow misusing the api? is this a bug? How can I work around it?

Jarrod Taylor (Clojure team)00:01:53

I am successfully sending messages with the following:

👍 1

Thanks @U0508JRJC I reported this problem over a month ago. I appreciate this solution.

Jarrod Taylor (Clojure team)14:01:34

You are both welcome. It took longer that I would have liked to workout all the parts of a functioning websocket implementation through API Gateway. I have a blog post in the works that walks through the full process of implementing an authenticated websocket. My hope is it will save others significant time when endeavoring to do the same.

Ben Hammond17:01:24

do you know of a way to pass an x-api-key HttpHeader in the initial js/WebSocket() call? Do you authenticate AFTER the WebSocket is hooked up?


I am trying to adapt sente to an api gw solution.


Does DefaultAwsRegionProviderChain also work for AWS Fargate tasks? The seems to imply no. > AWS Region provider that looks for the region in this order: > 1. Check the 'aws.region' system property for the region. > 2. Check the 'AWS_REGION' environment variable for the region. > 3. Check the {user.home}/.aws/credentials and {user.home}/.aws/config files for the region. > 4. If running in EC2, check the EC2 metadata service for the region.


I remember having to specify AWS_REGION for Fargate tasks


so maybe DefaultAwsRegionProviderChain doesn't use the AWS_CONTAINER_CREDENTIALS_RELATIVE_URI that is available when running in ECS


not sure, but would explain why I remember having to manually specify AWS_REGION


I remember having to do that for python libs too, wondering is there some reason for this...


heh, looked too quick, that metadata service in ECS that I was remembering might be only for the credentials, like it kinda says in that environment variable name.. so maybe (str "" (System/getenv "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI")) gives only the api keys, not the region, would have to check


so I guess the answer is that no


but interestingly, you can read stuff from the ECS metadata server and deduce the current region from say ARNs 😄

sh-4.2# curl -s  | jq -r '.ContainerARN' | cut -d: -f4


but if you know the region where you deploy to, depending on the deploy system, I guess specifying the region at deploy time as environment variable in the task definition isn't that bad (I've been using Terraform so you could read the current region from the aws provider)


or then hack and use say ContainerARN 🙂


also, if you manually specify region, then you don't need DefaultAwsRegionProviderChain


the above curl thing I quickly explored with, running a shell in the container and looking at the env


Here's the ECS creds provider that we have in use in prod for over a year: no issues whatsoever


the region only comes in play when making calls against AWS APIs so we set that as application level configuration

👍 1