How to send large Flux<Object> to Spring Web Flux via POST? - reactive-programming

Currently, working on developing reactive web applications for data processing application. I have a back-end service written in Spring WebFlux accepts
applcation/stream+json as a media type.
I am trying to send a array of json documents in the request body. The number of documents depends on the number of products being uploaded. Typically (250 to 10000) payloads can be uploaded. I want to send these payloads to the URL,
POST http://localhost:8080/products using Angular 5.
Request Body
[{
"id": "B001",
"description": "T-Shirt",
"price": 250
},
{
"id": "B002",
"description": "Shirt",
"price": 220
},
{
"id": "B003",
"description": "Jeans",
"price": 210
},
......]
The problem is, some times takes only 25 or 49 or 55 or 0 payloads in the backend. However, I am able to see sending all the payloads in the request (Browser Network terminal).
I think, i have to send these request using Event Source in angular 5, However, I am unable to find some examples. Your inputs are much appreciated!!.
Thanks!!

Related

How to analyze requests (with queries) on swagger and send different response body?

Is that possible to analyze the request (based on queries) on swagger hub api 3.0?
For example, I need to reproduce the next thing.
For request getUser?id=1 swager swagger has to send response to client
{
"user_id": "1"
"user_name": "Alex",
}
For request getUser?id=2 swager swagger has to send response to client
{
"user_id": "2"
"user_name": "Bob",
}
If that possible, could you help me with this please?
I guess your question is about SwaggerHub mock server. According to the documentation, this is not supported:
Note that the mock does not support business logic, that is, it cannot send specific responses based on the input.

REST Partial update on multiple resources

I have two sorts of resources, stores and items, a store can uniquely be identified by by it's ID, a store contains a number of different types of items.Items have codes to generally identify their type , for instance a conductor cable of modelA has a code of 265, an item of code 265 can exist in more than one store.
Sample HTTP requests and their responses.
GET /stores/1/items
[{
"itemCode": 265,
"itemDescription": "Conductor cable",
"itemModel": "model1",
"uom":"meter",
"quantity": 30
},
{
"itemCode": 122,
"itemDescription": "Low-fat Milk",
"itemModel": "model2",
"uom":"liter",
"quantity": 15
}]
GET /stores/2/items
[{
"itemCode": 265,
"itemDescription": "Conductor cable",
"itemModel": "model1",
"uom":"meter",
"quantity": 25
}]
GET /stores/3/items
[{
"itemCode": 122,
"itemDescription": "Low-fat Milk",
"itemModel": "model2",
"uom":"liter",
"quantity": 20
}]
what i would like to have is a REST Api endpoint that would let the Api consumer move, say 10 meters of conductor cable of model1 from store 1 to store 2.
I know there is the option of having two PATCH HTTP requests to achieve this by updating quantities in stores 1 and 2 but I need to achieve this with a single HTTP request.
If you want to achieve this using HTTP PATCH then JSON Patch - RFC 6902 should prove helpful. It allows sending multiple operations within a single request so it is possible to update multiple resources and properties at the same time. If any operation fails then the whole patch should fail as well. However within a request you have to specify the new final quantity of an item. You can't define an operation to subtract from the current value. So in order for this solution to work in a multiuser environment optimistic locking mechanism is a must. Otherwise data corruption is bound to happen.
HTTP POST is a good alternative. Moving some quantity of an item from one store to another is akin to transfering money between bank accounts. In this case I would consider creating the following endpoint: POST /stores/item-transfer. The request body would contain the source store/itemCode/itemQuantity and the target store. All state modifications would happen within a single transaction.
Personally I'm in favor of the POST approach however if you stick to PATCH and Java is your language then I'd suggest using the Tomoko library to process RFC 6902 requests. I'm its author.

REST API sub resources, data to return?

If we have customers and orders, I'm looking for the correct RESTful way to get this data:
{
"customer": {
"id": 123,
"name": "Jim Bloggs"
"orders": [
{
"id": 123,
"item": "Union Jack Keyring",
"qty": 1
}, {
"id": 987,
"item": "London Eye Ticket",
"qty": 5
}
]
}
}
GET /customers/123/orders
GET /customers/123?inc-orders=1
Am I correct that the last part/folder of the URL, excluding query string params, should be the resource returned..?
If so, number 1 should only return order data and not include the customer data. While number 2 is pointing directly at customer 123 and uses query string params to effect/filter the customer data returned, in this case including the order data.
Which of these two calls is the correct RESTful call for the above JSON..? ...or is there a secret number 3 option..?
You have 3 options which I think could be considered RESTful.
1)
GET /customers/12
But always include the orders. Do you have a situation in which the client would not want to use the orders? Or can the orders array get really big? If so you might want another option.
2)
GET /customers/123, which could include a link to their orders like so:
{
"customer": {
"id": 123,
"name": "Jim Bloggs"
"orders": {
"href": "<link to you orders go here>"
}
}
}
With this your client would have to make 2 requests to get a customer and their orders. Good thing about this way though is that you can easily implement clean paging and filtering on orders.
3)
GET /customers/123?fields=orders
This is similar to your second approach. This will allow clients to use your API more efficiently, but I wouldn't go this route unless you really need to limit the fields that are coming back from your server. Otherwise it will add unnecessary complexity to your API which you will have to maintain.
The Resource (identified by the complete URL) is the same, a customer. Only the Representation is different, with or without embedded orders.
Use Content Negotiation to get different Representations for the same Resource.
Request
GET GET /customers/123/
Accept: application/vnd.acme.customer.short+json
Response
200 OK
Content-Type: application/vnd.acm.customer.short+json
{
"customer": {
"id": 123,
"name": "Jim Bloggs"
}
}
Request
GET GET /customers/123/
Accept: application/vnd.acme.customer.full+json
Response
200 OK
Content-Type: application/vnd.acme.customer.full+json
{
"customer": {
"id": 123,
"name": "Jim Bloggs"
"orders": [
{
"id": 123,
"item": "Union Jack Keyring",
"qty": 1
}, {
"id": 987,
"item": "London Eye Ticket",
"qty": 5
}
]
}
}
The JSON that you posted looks like what would be the result of
GET /customers/123
provided the Customer resource contains a collection of Orders as a property; alternatively you could either embed them, or provide a link to them.
The latter would result in something like this:
GET /customers/123/orders
which would return something like
{
"orders": [
{
"id": 123,
"item": "Union Jack Keyring",
"qty": 1
},
{
"id": 987,
"item": "London Eye Ticket",
"qty": 5
}
]
}
I'm looking for the correct RESTful way to get this data
Simply perform a HTTP GET request on a URI that points to a resource that produces this data!
TL;DR
REST does not care about URI design - but on its constraints!
Clients perform state transitions through possible actions returned by the server through dynamically identified hyperlinks contained within the response.
Clients and servers can negotiate on a preferred hypermedia type
Instead of embedding the whole (sub-)resource consider only returning the link to that resource so a client can look it up if interested
First, REST does not really care about the URI design as long as the URI is unique. Sure, a simple URI design is easier to understand for humans, though if compared to HTML the actual link can be hidden behind a more meaninful text and is thus also not that important for humans also as long as they are able to find the link and can perform an action against it. Next, why do you think your "response" or API is RESTful? To call an API RESTful, the API should respect a couple of constraints. Among these constraints is one quite buzzword-famous: hypertext as the engine of application state (HATEOAS).
REST is a generalized concept of the Web we use every day. A quite common task for a web-session is that a client requests something where the server sends a HTML document with plenty of links and other resources the client can use to request further pages or stream a video (or what ever). A user operationg on a client can use the returned information to proceed further, request new pages, send information to the server etc, etc. The same holds true for RESTful applications. This is was REST simply defines as HATEOAS. If you now have a look at your "response" and double check with the HATEOAS constraint you might see that your response does not contain any links to start with. A client therefore needs domain knowledge to proceed further.
JSON itself isn't the best hypermedia type IMO as it only defines the overall syntax of the data but does not carry any semantics, similar to plain XML which though may have some DTD or schemas a client may use to validate the document and check if further semantic rules are available elsewhere. There are a couple of hypermedia types that build up on JSON that are probably better suited like f.e. application/hal+json (A good comparison of JSON based hypermedia types can be found in this blog post). You are of course entitled to define your own hypermedia type, though certain clients may not be able to understand it out of the box.
If you take f.e. a look at HAL you see that it defines an _embedded element where you can put in certain sub-resources. This seems to be ideal in your case. Depending on your design, orders could also be a resource on its own and thus be reachable via GET /orders/{orderId} itself. Instead of embedding the whole sub-resource, you can also just include the link to that (sub)resource so a client can look up the data if interested.
If there are cases where you want to return only customer data and other cases where you want also to include oder data you can f.e. define different hypermedia types (based on HAL f.e.) for both, one returning just the customer data while the other also includes the oder data. These types could be named like this: application/vnd.yourcompanyname.version.customers.hal+json or application/vnd.yourcompanyname.version.customer_orders.hal+json. While this is for sure an development overhead compared to adding a simple query-parameter to the request, the semantics are more clear and the documentation overhead is on the hypermedia type (or representation) rather then the HTTP operation.
You can of course also define some kind of view structure where one view only returns the customer data as is while a different view returns the customer data including the orders similar to a response I gave on a not so unrelated topic.

Uber API offers Uber Pool option + ability to send text message to drivers?

Does the Uber API offered "Uber Pool" ride type when we requests price / time estimates? Also, when a ride is coming, do we have access to a phone number in order to text the driver?
This isn't so much of an API issue as it is a feature question / request that a lot of our users wanted. I contacted Uber's support team via email and they told me to post anything API related in StackOverflow...
Does the Uber API offered "Uber Pool" ride type when we requests price / time estimates?
According to the GET /v1/products API endpoint documentation:
Some Products, such as experiments or promotions such as UberPOOL and UberFRESH, will not be returned by this endpoint.
Therefore, UberPOOL products are not avaliable through the Uber API.
Also, when a ride is coming, do we have access to a phone number in order to text the driver?
After you make a ride request using the POST /v1/requests API endpoint the first state the ride will be in is the processing state, to which you'll receive a response similar to:
Status-Code: 202 OK
{
"request_id": "852b8fdd-4369-4659-9628-e122662ad257",
"status": "processing",
"vehicle": null,
"driver": null,
"location": null,
"eta": 5,
"surge_multiplier": null
}
And as you can see you don't have access to any driver information in this state.
Then, as per the life cycle of a request, the request flow needs to move from the processing state to the accepted state, once a driver accepts your request.
The accepted state is the first state where you have access to driver details by either calling the GET /v1/requests/current or GET /v1/requests/{request_id} API endpoints.
You can know when the status changes either via a callback on your webhook or by polling at a 3-5 seconds interval one of the above Uber API endpoints to get the current status.
The HTTP response you receive after making one of the above HTTP requests looks something like this:
{
"request_id":"852b8fdd-4369-4659-9628-e122662ad257",
"status":"accepted",
"location":{
"latitude":37.7886532015,
"longitude":-122.3961987534,
"bearing":135
},
"pickup":{
"latitude":37.7872486012,
"longitude":-122.4026315287,
"eta":5
},
"destination":{
"latitude":37.7766874,
"longitude":-122.394857,
"eta":19
},
"driver": {
"phone_number": "(555)555-5555",
"rating": 5,
"picture_url": "https:\/\/d1w2poirtb3as9.cloudfront.net\/img.jpeg",
"name": "Bob"
},
"vehicle":{
"make": "Bugatti",
"model": "Veyron",
"license_plate": "I<3Uber",
"picture_url": "https:\/\/d1w2poirtb3as9.cloudfront.net\/car.jpeg"
},
"surge_multiplier":1.0,
"eta": 5
}
At this point you have access to the driver's phone number which you can use to call or text.

RESTful API response for data transfer objects

I have this following scenario in my application. I am logged in as a user and i create a group. There is a REST api for creating the group (POST /groups/api/v1/groups) and getting the group details (GET /groups/api/v1/groups/{group id})
The response returned on success is not just the json representation of the group resource. Its a DTO which contains a lot of other information (to avoid multiple calls to the server)
For instance, the response can include
Actions that can be performed on the group (for ex: inviting a user to the group) and the corresponding urls that need to be hit for each action
Count of members in the group.
Recent activity in the group
Member information
etc
Right now the only client using the REST api's is the UI which needs additional information. If the APIs are exposed to developers later, they may not need all the information being returned. How do we handle rest responses in such scenarios where we have to return DTO's which contain more information?
Is it a good design to be returning dto's in rest response for GET or should be avoided?
It helps if you accept the fact that RESTful HTTP is noisy. The design compensation for the noise is caching, which you should try to use as much as you can to save server hits. A well-cached application can use multiple resources, rather than one large resource, because many of the requests will not ever leave the client.
As far as your specific question, use the expand query parameter to identify what child objects to include. You can further specify what properties of that child to include. For example,
GET /groups/api/v1/groups/12345
{
"id": 12345,
"name": "The Magnificent Seven",
"location": {
"self": "/groups/api/v1/locations/43"
}
}
GET /groups/api/v1/groups/12345?expand=location
{
"id": 12345,
"name": "The Magnificent Seven",
"location": {
"self": "/groups/api/v1/locations/43",
"longitude": "24°01′N",
"latitude": "104°40′W"
}
}
GET /groups/api/v1/groups/12345?expand=location[latitude]
{
"id": 12345,
"name": "The Magnificent Seven",
"location": {
"self": "/groups/api/v1/locations/43",
"latitude": "104°40′W"
}
}
Well giving more data than required can prove to be harmful and you need to start explaining everyone why you are giving so much data. You can have a query param that is secret to a subset of users say "alldetails=true" which will give the full DTO.
If you are using Java with codehaus or some other JSON utility on the REST server you can specify what elements to expose by using a mixin. codehaus has "addMixInAnnotations()" for that.
A good REST response for GET should have an identifier, required details and URLs in JSON or XML.