LoopBack: How do I use PUT to replace an entry - rest

I struggle a bit with a basic PUT in a LoopBack project, but I cannot find any information about my problem. If use PUT to add an entry everything works fine, I just pass my data and there is a new entry in the database. Now I want to replace an entry, as described in the documentation for PUT (I am using the API explorer for my tests). My idea was to pass an 'id' (in addition to the changed data) and LoopBack would replace the corresponding entry. But that does not work, I get the error:
The `Model` instance is not valid. Details: `id` can't be set
How can I use PUT to replace an entry?

The id property in the PUT payload should be optional. If you're using the standard Loopback model CRUD endpoints that are set up during model generation you have two options:
Using the PUT /ModelName/{id} option where LB will find the model instance based on the query parameter passed into the URL.
Using the POST /ModelName/{id}/replace endpoint. This endpoint will replace all attributes of a given model instance based on the id that's passed into the URL.
Passing in the id property in the payload of the request is optional for both endpoints. Loopback will find the model instance based on the id param of the URL.

Related

Mapping multiple values for x-amazon-apigateway-integration.requestParameters for a single key?

I'm trying to create a new API on Amazon API gateway but for my use-case I want to concatenate 2 values for a single key in request parameters. How can we specify multiple values for a single key in integration.requestParameters?
This is what I'm trying to achieve but the syntax is not correct and it's giving me error:
For one to one mapping we use something like this
integration.request.querystring.start: "method.request.querystring.oauth_code"
Documentation link
I was able to solve it by following instructions in this Stackoverflow Answer.
Basically you need to add multiple parameters in the endpoint URL itself in the integration request, make sure that you are accepting those parameters as URL Path Parameters in the Integration Request.

How does one get all query params from within a endpoint?

I'm writing a toy finch project and trying to allow requests to specify arbitrary query parameters to set some value. I am able to retrieve the value for a known parameter name (i.e. param[String]("foo")) but how can I get a Map[String,String] of all the query parameters?
i.e. hit /myendpoint?foo=bar&baz=baq and within the response handler be able to access the value Map("foo"->"bar", "baz"->"baq")
I looked in the docs and there seems to be some way to access all the headers but no equivalent functionality is given for accessing params.

Is there a way to prevent Spring Cloud Gateway from reordering query parameters?

Spring Cloud Gateway appears to be reordering my query parameters to put duplicate parameters together.
I'm trying to route some requests to one of our end points to a third party system. These requests include some query parameters that need to be in a specific order (including some duplicate parameters), or the third party system returns a 500 error, but upon receiving the initial request with the parameters in the proper order, the Spring Cloud Gateway reorders these parameters to put the duplicates together by the first instance of the parameter.
Example:
http://some-url.com/a/path/here?foo=bar&anotherParam=paramValue2&aThirdParam=paramValue3&foo=bar
Becomes:
http://some-url.com/a/path/here?foo=bar&foo=bar&anotherParam=paramValue2&aThirdParam=paramValue3
Where the last parameter was moved to be by the first parameter because they had the same name.
The actual request output I need is for the query parameters to be passed through without change.
The issue lays in the UriComponentsBuilder which is used in RouteToRequestFilter.
UriComponentsBuilder.fromUri(uri) is going to build up a map of query params. Because this is a LinkedMultiValueMap you see the reordering of the used query params.
Note that RFC3986 contains the following
The query component contains non-hierarchical data that, along with data in the path component (Section 3.3), serves to identify a resource within the scope of the URI’s scheme and naming authority (if any).
Therefor I don’t think there needs to be a fix in Spring Cloud Gateway.
In order to fix this in your gateway, you'll need to add a custom filter which kicks in after the RouteToRequestFilter by setting the order to RouteToRequestUrlFilter.ROUTE_TO_URL_FILTER_ORDER + 1.
Take a look at the RouteToRequestUrlFilter how the exchange is adapted to go to the downstream URI.
Hope that helps! :)

Modify Rest POST request behavior with query String

I have a resource which basically represents a number. I have two possible updates for this number: Set the number to a specific value or add a value to it. Now I'm confused if I can use the query string part of the URL to specify the desired behavior.
Something like this:
/resource/{id}/?mode=add
/resource/{id}/?mode=set
Or is there an alternative way two represent to update strategies for a rest resource?
An Alternative would be to extend the request body with this information but this since strange, since the request data should contain the data and not "meta information" for the request itself - as far as I understand REST apis.
The project is an ordinary angularjs (client) and java (server) project.

RESTful url - getting new subentity

There are 2 models: Entity and Subentity. Entity can have many connected Subentities (one:many relation).
There is a method on server that returns new Subentity (let's call it GetEmptySubentity). Point is, when you want to create new Subentity, you press a button, and model comes from server with some fields pre-filled. Some of those Subentity pre-filled values depend on according Entity, so I need to pass an Entity id in this request.
So should the correct url to get the empty Subentity be like /Entity/{id}/Subentity/empty? Or I am getting something wrong?
Yes you are. According to the uniform interface / hateoas constraint you should send hyperlinks to your REST clients and they should use the API by following those hyperlinks. In order to do this you need a hypermedia format, for example HTML, ATOM+XML, HAL+JSON, LD+JSON & Hydra, etc... (use google). So by HTML the result should contain a HTML form with input fields having default values, etc... You should add semantics to that for with RDFa and so by processing the HTML your REST client will know, that the link is about creating a new resource. Ofc it is easier to parse the other hypermedia formats. By them you can use the same concept with RDF (by JSON-LD or ATOM for example), or you can use link relations with vendor specific MIME types (by HAL or ATOM for example), or your custom solution which describes those input fields. So you usually get the necessary information with the hyperlink, and you don't have to send another request to get the default values.
If you want to make things complicated, then you can send a request for the default values to the entity itself in order to send the values of properties, and not to send a form with input fields. Optionally you can send a request which returns the entire link, for example GET /Entity/{id}/SubEntity/offset=0&count=0 can return an empty array of subentities and the form for creation. You can use additional query or path parameters if that form is really big, and you don't want to send it with every response related to the SubEntity collection. The URL specification says only that the path should contain the hierarchical part and the query should contain the non-hierarchical part of the URL.
Btw. REST is just a delivery method, you don't have to map it to your database entities. The REST resource and URL structure can be completely different from your database, since you can use any type of data storage mechanisms with REST, even the file system...