I have deployed a simple REST based application in RAD.
A simple URL is accessed using http://localhost/<contextroot>/users/<username> where <username> is accessed using reqeust.getAttributes(). Now, how do i pass more than one attribute to the REST service?
Usually you'll use query parameters:
http://localhost/<contextroot>/users/<username>?a=10&b=hello
You haven't indicated which language or framework you are using so I can't tell you how to do this in code.
You could also use URLs of the style http://localhost/<contextroot>/comments/<username>/after/<date>, but that tends to get messy if you wish to include a large number of options.
Related
I have an endpoint that I am using to download a file. http://apiendpoint.com/file
We recently got a request to have a second file that we want to be able to get to and I want to add a query string parameter to it. http://apiendpoint.com/file?fileType="A"
I can do in the console but I want to add it to the cloudformation template and haven't been able to figure out how to do so. Any help would be greatly appreciated.
Since you are talking about using a parameter, you won't be able to do this in your cloudformation template, you'll have to implement that in the implementing service (i.e., the service that your API sends the requests to). API gateway in general is only granular to the path level and can only define path level parameters. And by that I mean define, not interpret (unless you're using advanced template mappings maybe, but from your template, it doesn't look like you are).
Oh, and you should have a look at AWS SAM. It could help with cleaning up your template and making it more readable and easier to interpret since it adds some abstraction.
I want to create a brand new REST API using MarkLogic 9.x.x but without using Roxy or Gradle. I want to point to a file which has list of customized endpoints in basic MarkLogic setup and then keep my customized logic in those modules.
I've gone through the REST API documentation to create one by using CURL so that we can use default APIs provided by MarkLogic.
Any detailed explanation is appreciated.
Management REST api is really your best friend here, it is designed for this purpose. However, creating scripts that make the appropriate REST calls can be cumbersome. ml-gradle can support you with that though. It can generate a shell-script with all curl-statements for you, which you could run as-is, or use as starting point to build out your own set of deploy scripts. For details see:
https://github.com/marklogic-community/ml-gradle/wiki/Generating-a-shell-script
HTH!
Have you considered using XQRS ?, you can create custom REST endpoints with ease using intuitive Function Annotations much like one would do with JAX-RS or Java Spring REST Services. It can be installed and used with or with-out Gradle.
You can keep your custom logic either in these REST functions, or you could write your custom logic in JavaScript code that you then import/invoke from these functions. XQRS provides you with total flexibility. You can make beautiful REST APIs with Human-Friendly URLs that sit directly on MarkLogic, taking complete control of the URL Path. It's solid as a rock and unit tested to death. It scales with MarkLogic - i.e. you add more MarkLogic e-nodes and you automatically scale your REST servers, it's totally free and open source. The project is actively maintained and support is available on GitHub. If you've got a Swagger/OpenAPI interface file, you can generate a MarkLogic Stub too which could save you a lot of time.
Functions simply become available as REST Services based on the Annotations you place on them - and you can pass query/form parameters, cookies and the request body via the Annotations. Check out this snippet for a sample flavour.
declare
%rest:path("/factory/warehouse/wheel/{$wheel-id}")
%rest:GET
function get-wheel($wheel-id as xs:string) {
fn:doc($wheel-id)
};
declare
%rest:path("/factory/warehouse/wheel/{$wheel-id}")
%rest:PUT("{$doc}")
%xdmp:update
function put-wheel($wheel-id as xs:string, $doc as document-node(element())) {
xdmp:document-insert($wheel-id, $doc, map:entry("collections", "wheels"))
};
declare
%rest:path("/factory/warehouse/wheel")
function list-wheels() {
<wheels>{
fn:collection("wheels")
}</wheels>
};
Both responses to date are correct and accurate and help, however the original question is self-answered.
I've gone through the REST API documentation to create one by using
CURL so that we can use default APIs provided by MarkLogic.
That is in fact the answer to your question as stated.
To manually deploy ML rest API, please follow below steps
Create Module DB
Create App Server
Provide details for Module DB, database, port, URL rewriter
Deploy xquery, xsl using qConsole
let URI = path of file
let path = xdmp:document-get($FilePath)
xdmp:document-insert($URI,$path,(), ())
where endpoints.xqy will contains defined custom endpoint for your rest API and internally you can call search:search function to call data from MarkLogic
module namespace endpoints="urn:overstory:rest:modules:endpoints";
declare namespace rest="http://marklogic.com/appservices/rest";
(: ---------------------------------------------------------------------- :)
declare private variable $endpoints as element(rest:options) :=
<request uri="^/getcontent$" endpoint="<xqy file" user-params="allow">
<http method="GET"/>
</request>
Hope this will help
I don't have Gateway available in my landscape and I want to use the ABAP REST library to expose web services: SAP Library - REST Programming Tutorial
With a very simple example, I successfully created a class to read a single domain list of values, the GET call is quite simple:
http://mydomain/domainvalues/XFELD
And the GET implementation is in my class ZCL_REST_DOMAIN_VALUES extending from CL_REST_RESOURCE implementing IF_REST_RESOURCE~GET method.
Now I want to make it possible to read or query multiple domains. I'm not an expert in REST but I've seen two options searching around, one using the same URI as the single entity and one with special URI for queries.
http://mydomain/domainvalues?Id=XFELD,WERKS_D
http://mydomain/query/domainvalues?Id=XFELD,WERKS_D
In the backend, should I use the second approach and create a class only for this call named for instance ZCL_REST_DOMAIN_VALUES_QUERY implementing the GET method again?
Or maybe should I use POST method to send the list of IDs to fetch in the body?
SAP's own in-house guidelines recommend to shape OData and plain REST services alike, to avoid confusion and facilitate switching between the two:
http://mydomain/domainvalues?$filter=Id in ('XFELD', 'WERKS_D')
Both would be served by the same REST endpoint handler class, although of course you are free to create separate methods or delegates for the cases.
Remember to sanitize (= whitelist/blacklist/escape) the query parameters before handing them over to some lower level to prevent SQL injection attacks, as #SandraRossi correctly pointed out below.
I am using making two http calls to Assyst REST api to fetch Priority value and closure action value like as follows.
> http://localhost:8989/assyst/assystGOLD/Priority?shortCode=%225%22&fields=name,shortCode&fmt=xml
> http://localhost:8989/assyst/assystGOLD/ActionType?shortCode=%22closure%22&fmt=xml
Now I want to merge these two url's to work in a single call. So I made below URL, but no luck.
http://localhost:8989/assyst/assystGOLD/ActionType?shortCode=%22closure%22&Priority?shortCode=%225%22&fields=name,shortCode&fmt=xml
Can anyone help me on this?
This isn't possible I'm afraid. The REST API only works with a single resource (Priority and Action Type in your example) in each request. You need to make two requests to get these two unrelated pieces of information.
Your example is using the legacy API's syntax. I recommend using the new REST API for new development - it is embedded within the main assyst Enterprise application and has much improved performance.
Paul
When writing a RESTful API that needs to access different environments such as a lab/test database and a production database, what's the best practices around setting up the API?
Should there be a #PathParam?:
/employee/{emp_id}/{environment}
/{environment}/employee/{emp_id}/
Should there be a #QueryParam?:
/employee/{emp_id}/?environment="test"
/employee/{emp_id}/?environment="prod"
Should there be a field in the payload?:
{"emp_id":"123","environment":"test"}
{"emp_id":"123","environment":"production"}
In fact I see two ways to handle this. The reason to use one or the other corresponds to what is the most convenient to implement in your RESTful application.
Using a path parameter
With this approach, it should be a path parameter at the very beginning of the resource path. So URL would be like this: /{environment}/employee/{emp_id}. Such approach is convenient if you have several applications deployed under different root paths. For example:
/test: application packaged with the configuration for the test environment
/prod: application packaged with the configuration for the production
In this case, applications for each environment are isolated.
Using a custom header
You could also a custom header to specify on which environment to route. Github uses something like that to select the version of the API to use. See this link: https://developer.github.com/v3/#current-version. It's not exactly the same thing but you could have something like that:
GET /employee/{emp_id}
x-env: test
A reverse proxy could handle this header and route the request to the right environment.
I'm not convinced by the approach within the payload since an field environment isn't actually a part of the representation for element resource employee. Regarding the query parameter approach, it's similar since such parameters apply to the request on the resource.
Hope it helps you,