I have a legacy application which currently utilises a SOAP interface to invoke functions against.
I wish to serve this interface to a website, with it being preferential to be done using REST with a JSON scheme.
I wish to get feedback and validate my thinking for the solution to this problem as described below:
In order to do the transformation from SOAP (XML) <--> REST (JSON) I am planning on using the following components:
Amazon API Gateway: Receives a POST request from my website containing basic payload data.
Lambda Function: API Gateway invokes an AWS lambda function which is contains a soap client package. The function handles any necessary transformations and mappings and it is the Lambda function which issues the request to my legacy SOAP service.
SOAP service: Receives request, executed required function and returns XML response
Lambda Function: Receives response, parses any required data / handles any errors and returns the response call back to the API Gateway.
API Gateway: Returns result of Lamdba function invocation.
A few questions:
I am unsure whether it is the Lambda function which carries out the request directly to my SOAP service, I am assuming so as this is just an encapsulated function. Is this correct?
Does the Lambda function return the response back to the gateway request? I believe this is correct as the function can execute synchronously so will still have the context to return the response back.
Do you generally handle any authentication checks within the API Gateway for the initial inbound request or does the request in its entirety get passed down to the Lambda function where I would then conduct and execute any auth policies/checks?
For Question 1 & 2:
Yes, it is correct to do the SOAP request and transformation in the Lambda function.
For Question 3: To handle authentication at API Gateway, you can use a separate Lambda function called Custom Authorizer. You can also do authorization for API Gateway endpoints in Custom Authorizer Lambda function.
Related
A little preface
I am making a REST server (FastApi) that will act as a REST gateway to other network devices. This server currently has a general purpose REST "forwarding" endpoint /query/{device_host} that takes the following body:
{
method: "GET", # Can be any REST method
headers: { ... }, # Dictionary of header key-val strings
url: "http://<device_host>?<optional_queries>", # Url to send request to
body: { ... } # JSON Dictionary of arbitrary shape
}
and passes it to a REST Session Manager object that deals with sending/receiving the request/response.
Dilemma
I want to make routes that send pre-defined REST queries, sort of like shortcuts to the general endpoint above. For example a POST REST request to /query/{device_host}/configure_logs could, by default, add the following to the request body if not already specified:
{
method: "POST",
headers: { "Content-Type": "application/json" },
url: "http://<device_host>/setup/log_server",
body: { "server_port": 10101, "server_url": "10.10.10.10" }
}
and pass it to the REST Session Manager and that is that, which is one approach.
However I figure, instead of passing it directly to the REST Session Manager, I could internally redirect the request(w/ status code 308 I believe as I want to pass the body along) to the general endpoint /query/{device_host}. Some pros/cons to this approach that I can think of:
Pros
Decreases code duplication (which really would only be calling the REST Session Manager)
Decreases required body argument as there are now defaults
Any middleware around the general REST endpoint will affect the pre-defined REST endpoints
Collecting metrics around the forwarded REST requests is easier as we really only need to monitor the general REST endpoint
Cons
Additional latency (unsure if internal redirects add much latency)
Additional I/O
I am also unsure if redirects are, in general, recommended for a REST microservice.
Is there any reason I should prefer one approach over the other?
I'm using JMeter to test a microservice and I need to use a parameter dynamically with a different value in each request. Also, the parameter is a part of a query that contains other constant values as well.
I defined user variables in the JMeter user.properties file (in JMeter bin folder):
JMeter -- bin/user.properties
# Parameters to use in JMeter
ES_HOST=127.0.0.1
ES_PORT=9200
ES_INDEX=segments
ES_TYPE=_doc
THREAD=5
CSVDATA_ROOT=C:/devtools/apache-jmeter-5.2.1/csv_data
Of course, I have User-Defined Variables:
And how my Test Plan is defined in JMeter
As you can see in the following screenshot of View Result Tree the parameter agentName I defined and shown in the HTTP Request (above) is working.
I want to define it in the body of the HTTP Request, to replace the hardcoded "John Doe" with a parameters that have a different value in each request.
"query":"SearchStartTime=2020-01-01 00:00:00.000TO2020-01-31 23:59:59.999&AgentName=John Doe"}
How can I do that?
I need a way to add a parameter to an existing string
I've already tried Using Apache JMeter to Test Elasticsearch (or any REST API) and In Jmeter, What would be syntax of parameters in Body Data section of HTTP Request Sampler, for Rest APIs and input should be generated dynamically also doesn't solve my problem.
Use same syntax as HTTP request - ${agentname} for getting variable value:
"query":"SearchStartTime=2020-01-01 00:00:00.000TO2020-01-31 23:59:59.999&AgentName=${agentname}"
I am trying to anonymize images before sending them to another Orthanc server.
According to the documentation on anonymization, Orthanc can anonymize images through the REST api:
http://book.orthanc-server.com/users/anonymization.html
Orthanc allows to anonymize a single DICOM instance and to download
the resulting anonymized DICOM file. Example:
$ curl http://localhost:8042/instances/6e67da51-d119d6ae-c5667437-87b9a8a5-0f07c49f/anonymize -X POST -d '{}' > Anonymized.dcm
According to the documentation page on Lua scripts, Lua scripts can take advantage of the REST API:
Lua scripts have full access to the REST API of Orthanc
The page goes on to describe how to use call the REST API from Lua:
functions:
RestApiGet(uri, builtin)
RestApiPost(uri, body, builtin)
RestApiPut(uri, body, builtin)
RestApiDelete(uri, builtin)
The uri arguments specifies the URI against which to make the request, and body is a string containing the body of POST/PUT request.
This means that I should be able to call the REST API from Lua by combining the functions above.
However when calling the RestApiPost as described in the documentation.
instances = RestApiGet(http://localhost:8042/instances, true)
I get the following error
E0313 17:40:40.851840 LuaScripting.cpp:358] Lua: Badly formatted URI
E0313 17:40:40.851884 LuaScripting.cpp:361] Lua: Error in RestApiPost() for URI: http://localhost:8042/instances/b38a8ef0-909f8ac0-7eca907a-75c98187-8e5339f4/anonymize
It's worth noting that I can call this endpoint correctly from curl and from my browser. Removing the 'http://' section didn't solve the issue.
The RestApiGet function and its family expect the developer to format the uri parameter without 'http://localhost:8042' as follows:
'/instances'
These functions only work for using the REST API provided by the Orthanc the Lua script is running on, so it already knows that you will use the localhost and it will use the correct http scheme and 8042 port automatically.
As described in http://book.orthanc-server.com/users/lua.html#general-purpose-functions, the function HttpGet(url, headers) and its family are the general form of this function and allow the developer to query any http endpoint.
I have a program that is trying to send a string for example http//:somewebsite.com using POST to my Lambda function via the AWS API Gateway. I know the API gateway only accepts JSON to be sent to Lambda, however, is there a way I can transform the string to JSON to be sent to Lambda within the API Gateway?
If you want to POST just url then please format your json like below,
{"Url" : "http//:somewebsite.com"}
I'm looking for a better way to structure my rest client/rest api code. Currently, I have my rest api with routes like:
get /book
The literal string "/book" is defined on the server side, and on the client side, I have to use the same literal string exactly.
What I would like to do is, have a file serverside which has all of my routes in it, and send it to the client as json, which the client uses for routing.
The basic workflow would be:
Start the server
When the client connects, make a get request for the routes object
return an object like this:
{
getBook:"/book",
createBook:"/book/create"
}
that way my client can use the object returned for the routes instead of hard coding them.
Is this a good idea?