Parse API: batch push notifications - notifications

I'm wondering how push notifications can be sent in batches. Let's look at the problem from the following 3 major patterns:
one API call -> one message -> delivered to a specified user
one API call -> one messages -> delivered to many different users (specified by id)
one API call -> many different messages -> delivered to many different users (specified by id)
The first one can be done easily.
The question is, what would you recommend to use for the second and the third ones?
I'm thinking of something similar to Facebook's Batch Requests when you have the ability to pass instructions for several operations in a single HTTP request. Is it possible at all with Parse?

for second pattern there is a way.
where parameter should be like this: where={"id":{"$in":[1,3,5,7,9]}}
more where parameters:
another example if you need to execute query for fining IDs:
still no workaround for third pattern

Related

How to define REST API with to Parameter

I am currently working on a REST API for a project. In the process I should search for events. I would like to make an endpoint for searching events in a period. That is, specify two parameters with from - to.
For the search you normally take a GET operation. My question is now it makes sense to specify two parameters in the path or should I rather fall back to a POST operation for something like that.
Example for the path /Events{From}{To}
Is this even feasible with multiple parameters?
If you are not making a change on the resource, you should use GET operation.
More detailed explanation:
If you were writing a plain old RPC API call, they could technically interchangeable as long as the processing server side were no different between both calls. However, in order for the call to be RESTful, calling the endpoint via the GET method should have a distinct functionality (which is to get resource(s)) from the POST method (which is to create new resources).
GET request with multiple parameters: /events?param1=value1&param2=value2
GET request with an array as parameter: /events?param=value1,value2,value3

REST bulk endpoint for fetching data

We(producer for the API) have an endpoint
/users/:{id}/name
which is used to retrieve name for the user 'id'
Now as a consumer I want to display the list of names for users like:
user1: id1, name1
uder2: id2, name2
where I have the ids in input.
In such a case should I make 2(here the list is dependent on UI pagination example 50) separate calls to the API to fetch information or else create/ask the producer to create a bulk endpoint like:
POST /users/name
body: { ids: []}
If later, then am I not loosing the REST principle here to fetch information using POST but not GET? If former, then I am not putting too much network overhead in the system?
Also since this seems to be a very common usecase, if we choose the POST method is there really a need of the GET endpoint since the POST endpoint can handle a single user as well?
Which approach should be chosen?
A GET API call should be used for fetching data. Since browser knows GET calls are idempotent, it can handle some situations on its own, like make another call if previous fails.
Since REST calls are lightweight, we tend to overuse API call repeatedly. In your case, since you want all name v/s id mapping at once, one call is sufficient. Or have a Aggregator endpoint in backend API gateway to reduce network traffic and make repeated calls nearer to actual service.
Keeping GET /users/:{id}/name , is also not a bad idea alongside this. It helps to abstract business functionality. A particular scenario can only allow single fetch.
Also using GET /users/name with pagination and returning list of names is complex for single use so keeping both are fine.

Cumulocity API call with Device Group or Device Type or multiple source

I would like to call the event/alert API but filter the results by Device Type or Device Group, or as a last resort with multiple sources. Is there a way to make a sigle call to the API to achieve this result? At the moment I use /inventory/managedObjects with a device type first to get a list of devices, and then loop through the results and make a call to events/alarms for every device but this doesn't seem like a good way to do it.
Currently there is no way to query event and alarm APIs for a collection of source IDs. You can only query by a single ID.
If you are completly unhappy with calling for every device in the group there are two workarouns that come to my mind:
You query all and filter on the client (the more groups you have the worse this method will be).
You can create an event processing rule that adds an additional fragment to every created alarm and event based on the device group (incoming alarm -> check source -> check parents of the source (there is a function findAllManagedObjectParent). E.g. you add:
"myDeviceGroupName": {}
to all alarms and events.
Afterwards you can query the APIs not by source but by fragmentType.

Rest API calls with side effects on other resources

Let's say I have a mobile app, android/iOS and a java Spring back end. Given the mobile connectivity, the number of network round trips must be limited, ideally, 1 or less per screen.
Now, let's say I want to add/rewrite some messaging capabilities when 2+ app users can send each other messages.
There are 2 tables / resources (simplified here). 'Conversation' and 'Message'. Each conversation contain multiple messages.
conversation
-----------------
id
type
last_message_test
last_message_username
message_count
etc
message
------------
id
conversation_id
user_id
user name
text
timestamp
The conversation records contain some information about the latest message that took place in it so that a screen listing just the header of many conversations can show its latest content without having to query the actual message table (also the message count).
ideally there would be calls like this:
POST /api/conversation => create a new conversation
POST /api/conversation/1234/message => post a new message in conversation 1234
GET /api/conversation?searchparam1=1&searchparam2=2 => retrieve certain conversation without their full actual content
GET /api/converstaion/1234/message => retrieve all the messages of a given conversation, 1234
Here are the problems though:
problem A)
When positing a new message, this creates a new message resource but their is also the side effect of an (async / messaging) update on the corresponding 'conversation' record. So POSTing a new resource of typeA triggers a PATCHing of another resource of typeB. Is that OK?
problem B)
When positing the first message, there isn't yet a conversation record. Both must be created, first the 'conversation' record, then the 'message' record that will contain the new conversation ID (ideally in a transaction). How to do that in a rest way without having to do 2 api calls?
Basically trying to find the right compromise between:
number of rest calls
duplicated db fields and queries
rest style of resource-oriented API
Maybe it's not really possible without adding some sort of artificial new resources or 'batch / bundle / aggregate' operations / end points? any recommendations appreciated, thanks!
I see a few ways to do this - though first off I would not worry so much about keeping the latest message in the conversation table. If the message table is indexed/stored correctly that should not be a limiting factor.
The POST to the /api/conversation endpoint can be a message that contains no conversation id. The service can create a new conversation and place the message at a new resource under that conversation:
/api/conversation/12345/1 <---- so message #1 on conversation #12345
You could have another path between the conversation number and the message number, but I don't see that being needed.
/api/conversation/12345?param=1 <---- better 'search' endpoint
I'm not sure why you would need a PATCH to be issued if you just keep adding to the resource (conversation) from it's endpoint.
Copied from StackExchange Autor: Eric Stein
Problem A) Yes, that's fine. RESTful POSTs are permitted to generate side effects on other resources. I'd suggest breaking out messages from conversations in your URI hierarchy in this case, or allowing clients to POST a message resource to /conversations to create a new conversation. It could respond with a Conversation Message with a "self" URI pointing to the newly created conversation and message.
Problem B) When you POST a new message, if it doesn't contain a conversation ID, have your service layer start a transaction that creates a new conversation, then creates the message with the conversation id. Your response from that POST can contain the conversation id for future calls.
I think that part of your problem is conflating a database table with a resource. It's often the case that the database model and resource model should be different, and I think this is a good example.
If you want to be able to update the screen in one call, figure out what information needs to be in the response to that call. Make that your resource. Clients can POST to /messages and get a response back containing something that isn't a message.
What REST is trying to push you towards is a state machine, where the resources are states, the requests are the inputs that determine which transition you make, and the response contains the new state after you complete the transition.
Unrelated but maybe helpful - it is a (loose) standard to use plurals for collection resources, so I would expect to see /conversations and /messages.

Which resource should I use to keep my API RESTFul?

I'm building an API to allow the client of the API to send notifications to remind a user to update an Order status. So far, there are two notifications:
when the user hasn't marked the order as received;
when the user hasn't marked the order as done.
I want to build this API to make it simple to extend to other notifications related to the order, but keep a simple URI for the clients of this API.
How can I define my resources in order to keep my API RESTFul?
I was thinking about having one of these structures:
Option 1:
POST: /api/ordernotification/receive/{id}
POST: /api/ordernotification/complete/{id}
Option 2 (omit the status from the resource and post it instead):
POST: /api/ordernotification/?id={id}&statusID={statusID}
EDIT
Option 2.1 (keeping an articulated URI, as suggested by #Jazimov):
POST: /api/ordernotification/{statusID}/{id}.
Which option is more appropriate? Is there any advantage that one option has over the other? Or are there any other option I haven't thought of?
I would go with something along these lines
POST /api/order/1234/notifications/not-received
POST /api/order/1234/notifications/not-completed
Which can later be accessed via
GET /api/order/1234/notifications/not-received
GET /api/order/1234/notifications/not-completed
Or
GET /api/order/1234/notification/8899
There's no real limitation on how semantically rich a URI can be, so you might as well take advantage of that and be explicit.
If I understand you correctly, you have two types of ordernotifications: those for notifying receive and those for notifying complete. If those are two separate data models then I think nesting them is a good idea (i.e. a table called ReceiveOrderNotification and CompleteOrderNotification). If that's the case then you may want to expose two different endpoints entirely, such as POST /api/receiveordernotification and POST /api/completeordernotification.
But I don't think that's the best you can do, given so many overlapping similarities there probably are between order notifications. Now, option 2 is more like a GET, since you're using query parameters, so with your first option let's collapse them into this:
POST: /api/ordernotification/
and then pass it some JSON data to create the notifications
{
"orderId": "orderId",
"userId": "userId",
"prompt": "not marked received/not marked done"
}
I also removed the /{id} because when you POST you create a brand new thing and the id has not been created yet, usually. Even if the client is creating an id and sending it to the API it is a good practice to leave it open so your API can handle creating a new, unique resource in its own way.
This is RESTful is because a POST creates a resource ordernotification with certain data points. Your first option made actions a resource in themselves but that's probably not represented in any data model in your backend. To be as RESTful as possible, your API endpoints should represent the database domains (tables, collections, etc). Then you let your controllers choose what service methods to use given the data sent in the request. Otherwise REST endpoints expose all the logic up front and get to be a long list of unmaintainable endpoints.
I think, to update status of already inserted records, your endpoint should be PUT instead of POST.
You can use
PUT: /api/ordernotification/:id/status/
with clients json data
{
"status": "your_status"
}
according to request data, endpoint should update the record.