Siesta Service configureTransformer for URL decode models based upon parameters - ios

I have an endpoint which supports post requests. The URL is the same for all requests but the parameters will be different for each request. It is basically a free-form query service when the client can formulate the query and fields that will be returned in the response. I would like to be able to define methods on the service which will represent specific queries and a model for each query. But I am uncertain as to how I would go about configuring the transformer for each "query based" endpoint.
Is there a way to accomplish this or is it best to simply work with a json dictionary?
Thanks...

I think that I found the solution to my problem and it was rather simple. It was just a matter of building the resource and supplying it to configureTransformer.
func getUserIds() -> Request {
let res = resource(endPoint)
.withParam("query", "SELECT id FROM users where status='Active'")
configureTransformer(res) {
try self.jsonDecoder.decode(UserIdResponse.self, from: $0.content)
}
return res.request(.post)
}

Related

Take all data from Zapier Storage

I need to get all the data from StoreClient (Javascript). The format of the data on the below picture, they are in Zapier Storage.
const store = StoreClient('mysecret');
const value = await store.getMany('mykey'); // or store.get('mykey')
return {result: value}
This code works well. But I need to take and process all stored keys in a loop along with all their child value. I did not find a way :(
I tried store.list_pop(key), but the lists have a different storage format. And the data is not retrieved.
I would recommend using Zapier's storage API which will allow you to retrieve all stored data through a GET request to https://store.zapier.com/api/records. I often have to do the same thing and this works for me.
Have a look at their documentation here. I typically code in Python using the requests library. But I'm sure you could achieve similar results using an ajax or fetch request in Javascript.
EDIT
If I am understanding your question correctly you are trying to 'GET' all of your data stored in Zapier's storage client. As per their API documentation:
Zapier stores your data as a dictionary object which can hold key value pairs. Those values can also be nested dictionaries or lists. Regardless of how you store the data (simple key value pairs, nested lists, nested dictionaries, or some combination of the preceding) a 'GET' request will return the entire object. As stated before I typically use Python's request library to handle HTTP requests but I was able to achieve the same result using a Javascript fetch request. I setup a dummy storage account at https://store.zapier.com/api/records?secret=dog to test and illustrate how this works. See my code below.
var url = "https://store.zapier.com/api/records?secret=dog";
const res = await fetch(url);
const body = await res.json()
return {JSON : body}
Unfortunately, due to my lack of familiarity with Javascript I had to bake the secret into the url, which I don't think is ideal, but for the purposes of this example it does the job. See my output below.
As you can see the 'GET' request returned all data stored in my Zapier storage account. I simply returned the data I retrieved from the 'GET' request but you could of course loop through the results and execute logic as needed. This does not modify any of the data stored, what I often do is pull in all of my stored date with a 'GET' request, modify it, delete the old storage, and 'POST' my modified storage information. This allows me to limit my requests to two calls rather than modifying each individual value.

Query single entity through Breeze+Odata via .../Entity/1L url

I am trying to load a single entity by its key from an OData server using BreezeJS. After some research, it seems that EntityQuery.fromEntityKey is the proper approach (since I also would want to add expand).
The intended query URL would be http://.../Customer(1L)?$expand=....
However with the following code:
let query = EntityQuery.fromEntityKey(new EntityKey("Customer", id)).expand("...")
return <Promise<Customer>><any> this.entityManager.executeQuery(query)
the URL is
http://.../Customer?$filter=CustomerId eq 1L & $expand=...
which is not entirely incorrect, but different from what would normally be used to request an entity.
How can Breeze be configured/called to get the "correct" URL?

deployd - post method to retrieve object

Trying to use deployd.com framework for simulating a backend service. I am fairly new to deployd, appreciate any example or pointer in the right direction. Trying to retrieve an object using POST method. It looks like POST is used to create objects.
In my case, POST data contains a few query fields that will be used to query an object and send json back. Is this possible using deployd by modifying onPost method or some other way?
I cannot use GET with query parms due to security restrictions.
here is post request data
[
{
customer:"sam",
city:"noWhere",
}
]
the POST event should query by customer and city, then return matching customer object
[
{
customer:"sam",
postcode:"352345",
city:"noWhere",
country:"US"
}
]

Ember.js find single item without ID

I’m building an Ember.js application, using Ember data, ActiveModel serializer, and Ember Simple Auth Devise, connecting to a Rails API and trying to understand how I could build a route that loads a single resource, in this case for a "my account" page for the current user.
From the Rails perspective I don't need an ID, but on the Ember side I’m not sure how to accomplish this. My workaround has been to supply a placeholder ID, which Rails ignores. Is there a better way to accomplish this?
Ember.js:
MyAccountRoute = Ember.Route.extend(model: -> #store.find 'account', '1')
Rails:
def show
#item = #current_user.account
end
Ember Data has a very specific implementation when you use find
find called with the type only expects a collection of that type, this maps to findAll
find called with the type and a primitive type (non object) will expect a single object response of that type, this maps to findById
find called with the type and an object will expect a collection (possibly filtered server side by the parameters sent in), this maps to findByQuery
So using Ember Data there is no way to do this, unless you want to hack it into one of your other implementations, or use ajax to call back and then sideload the store. I prefer using the pattern you're using, I do this.store.find('user', 'me'); And then ignore the parameter.
The way I am tackling this is by returning an array/collection of records that only contains a single record.
Then in Ember you can access this single result using .get('firstObject') like this
export default Ember.Route.extend({
model: function() {
return this.store.find('user').then(function (users) {
return users.get('firstObject');
});
}
});
This feels more like an Ember way of doing things and also avoids an issue you may notice if you use the Ember developer tools plugin; That the returned data actually creates a duplicate record - you end up with an empty record with an id of me or 1 and a complete record with the ID of the single record returned.
An alternative approach is continue using me or 1 and to set or modify the ID of the returned record to match. In this case you would return a single object and not an array/collection.
Ember data has queryRecord method.
This method makes a request for one record, where the id is not known beforehand
http://emberjs.com/api/data/classes/DS.Store.html#method_queryRecord
I combined the two answers and used queryRecord with a parameter ignored by server.
return this.store.queryRecord('user_settings', {id: 'me'});
thanks Binarytales and antulik

REST call may results in two different JSON objects. What design pattern should I use?

My web application makes a REST call. If the call is successful, it will return a 'weather' json object. If the call fails, it will return a json error object.
I want to make a class that parses the resulting JSON and returns a Weather object if the call succeeded and an Error Object if the call failed.
I'm thinking of using the Factory pattern but I'm not sure if that's a good approach because the two objects are very different from one another. What is a good way to design this code?
A common approach I use is to have Weather and Error both be Response objects and have a ResponseFactory create them.
I strongly encourage you to use proper HTTP codes when designing your service as they give a more general view of the state and success of each call.
You need first to check the result of the call, and then make a decision on how to handle it, with the possibility of handling all error codes with an error callback that returns an Error JSON object, and a success callback to return a Weather JSON object. You can use the HTTP codes to create a proper response and further subdivide the logic to return more specific errors, if needed.
The use of a Factory pattern seems overkill, specially given that the objects don't relate to each other.
It really depends on the environment you'll be using your API.
As a rule of thumb, rely on the HTTP code - if you get a 404 or a 500 of course you can't come up with a parsed response.
Format your error responses in a consistent way, e.g.
404 { "message" : "Resource not found" }
400 { "message" : "Wrong parameters given" }
So you know how to parse them.
If you get a 200 OKyou know everything was right, and you can parse your response with no problem at all.
Does the Content-Type header vary depending on the type of response?
As some have noted in their answers, the HTTP status code should be used to determine "Was there an error", but just as important is the interpretation of the content type returned.
Hoping the Content-Type header does vary, I would suggest using a registry of parsers, registered by content-type they handle, and then delegate to them to handle understanding how to convert a particular content type into the object you want. In Ruby, since you didn't specify a particular language:
case response.status:
when 200..299
return parsers[response.content_type].parse(response.body)
when 400..499
raise parsers[response.content_type].parse(response.body)
else
raise "Unhandled response status"
Doing so separates the two concerns:
Determining if there was an error
Parsing of content types into classes/types in your application.

Resources