Booking Ride with Uber API - uber-api

When I look up products I can get the product_id that has upfront_fare_enabled as true.
I then get the fare_id.
However when I use that fare_id to book a ride, I always get the error below;
{"meta":{},"errors":[{"status":422,"code":"upfront_fare_required","title":"A
valid fare_id is required to request a trip with this product."}]}
Also, the product_id that clearly says upfront_fare_enabled is true.
If I lookup that product id it just says
"{"fare":{"breakdown":[{"type":"base_fare","name":"Base Fare","value":10.4}],"value":10.4"}"}"
Nothing about upfront_fare_enabled.
I've cross-checked; the product_id is correct.
What am I doing wrong and how can I fix it?

This is covered in the API docs https://developer.uber.com/docs/riders/ride-requests/tutorials/api/curl
The Uber API lets you Request an Uber Product for riders. Given you
know a rider’s location, where they want to go, and which Uber product
they want, you can request a ride for them with a few simple API
endpoints.
In the products endpoint GET /products, products have the
upfront_fare_enabled field set to true.
Use the request estimate
endpoint POST /requests/estimate with a product_id to get a fare_id.
The fare_id is used to set an upfront fare and arrival time for a
trip. The fare_id expires after two minutes. If the fare_id expires or
isn’t valid, a 422 error is returned.
Request a ride using the request
endpoint POST /requests with the fare_id returned in the previous
step.
See the API docs for the two APIs here
https://developer.uber.com/docs/riders/references/api/v1.2/requests-estimate-post#example-response-with-surge-pricing
https://developer.uber.com/docs/riders/references/api/v1.2/requests-post#post-parameters

Related

Which http status code should be returned when the identifier in the payload does not exist?

I've the endpoint POST /permission-period which should create a permission period for a specific user.
The payload:
{
"userId": 10,
"permissionPeriodDateFrom": "2017-12-01",
"permissionPeriodDateTo": "2017-12-10"
}
If any property from the payload is invalid, i usually return 422 Unprocessable Entity, which means the syntax of the request payload is valid but it cannot be processed due to invalid data.
What status should I return if the user does not exist and I do not want to provide the client with this security related information? Should i expose the message that the user does not exist or not?
I think HTTP status code wise I would choose a 400 - Bad request. Regarding the returned error message I would give the user a helpful information while keeping security-related information secret.
You could return something like The given userId is either malformed, does not exist or cannot be linked to the posted resource. This would allow the user to identify the spot where in the body the error comes up (property userId) but does not tell him the exact error to prevent user enumeration.
The good news is that you obviously have a protected endpoint when creating a permission-period so the API user is identifiable and you can take other actions for preventing user enumeration and related brute force attacks such as consumer-based throttling or locking the API consumer after x attempts.
I hope my notes help you with your API design.

REST API: Should we validate every route parameter?

Let's take this route as an example:
GET /merchant/{merchant_id}/product/{product_id}
By REST API best practices we should validate both: merchant_id and product_id. Most of the times it's irrelevant as validating product_id is usually enough to get the Model.
Is there any practical reason we should validate both: product_id & merchant_id?
Please share your opinions on that.

REST API: resource needs to be filtered by ID, but no ID specified

Let's say I have a resource /books, with a parameter ?author_id=. What should be returned if no author_id parameter is specified, e.g., /books as opposed to /books?author_id=42? Based partially on this answer, I have decided that if you hit /books?author_id=42 you will get an empty collection if author 42 has no books, instead of e.g., returning a 404.
However, in the case that client_id is null, I am not sure if I should treat this case the same way (i.e., the author with the ID of null has no books) or if it should be something like a 400, treating null as an invalid value for client_id.
Note also that books is a contrived example, and that in my case, I cannot simply return all "books" if the user hits /books. Assume it is a case that only the author has access to their books.
Basicly, it's up to you, how you want to handle this.
I developed some RESTful API's according to the Microsoft REST API Guidelines, which contains best practices.
According to the their guidelines, REST Clients have to expect, that collection data can be returned in page-sizes.
And if you provide paged results, you also want to provide filtering to big collection; so filter a collection with an author.
They use 'OData' styled filtering, sorting and paging. I'll quote the actual 'filtering' chapter:
The $filter querystring parameter allows clients to filter a
collection of resources that are addressed by a request URL. The
expression specified with $filter is evaluated for each resource in
the collection, and only items where the expression evaluates to true
are included in the response. Resources for which the expression
evaluates to false or to null, or which reference properties that are
unavailable due to permissions, are omitted from the response
(answer to your question: which means you should return an empty paging result)
Example: return all Products whose Price is less than $10.00
GET https://api.contoso.com/v1.0/products?$filter=price lt 10.00
The value of the $filter option is a Boolean expression.
What should be returned if no author_id parameter is specified, e.g.,
/books as opposed to /books?author_id=42?
If the resource URL is valid /books, but server cannot serve this particular request then I will prefer HTTP 501 Not Implemented as response code. Because the server is responsible for not supporting this feature. This is debatable as some will prefer 4xx HTTP codes, but in my opinion 4xx error status codes points the finger at clients.
W3 Standard definition for HTTP 501
10.5.2 501 Not Implemented The server does not support the functionality required to fulfill the request. This is the appropriate
response when the server does not recognize the request method and is
not capable of supporting it for any resource.
.
I have decided that if you hit /books?author_id=42 you will get an
empty collection if author 42 has no books, instead of e.g., returning
a 404.
This is absolutely fine.
Next question -
However, in the case that client_id is null, I am not sure if I should
treat this case the same way (i.e., the author with the ID of null has
no books) or if it should be something like a 400, treating null as an
invalid value for client_id
This is fine too. As client is sending invalid id and it can be corrected from client side so 400 Bad Request is appropriate for this case.
First, in your example above, /books?author_id=42 is not restful imo (some religious discussion will no doubt occur). /books/42 would be "get me book with id=42". Instead, the API should take filter parameters from the body of the request as selection criteria. /books will include ALL books that match the embedded filtering criteria, null collection is a possibility.
If you want, the API can also check to see if some of the filtering criteria (author) is valid and return 404 if the author does not exist. That is an API decision, the UI just knows how to talk to it and handle the result.
Notice exactly what I predicted? Religious discussion along with downchecks. Read up on Roy Fielding's work and Leonard Richardson's elaboration.

shopify transaction api GET all transactions

since shopify's transaction reporting is broken, I'm trying to use the API to get transaction fees for orders and basic accounting. In their API docs, they have their endpoints and parameters listed for getting/posting transactions. To "Receive a list of all Transactions", the docs say
GET /admin/orders/#{id}/transactions.json
but don't explain what the #{id} is for. The call will only work if I put a transaction ID in, but then it only shows a single transaction, rather than a list. The docs state that to "Get the Representation of a specific transaction":
GET /admin/orders/#{id}/transactions/#{id}.json
Which has the id in there twice. I can't use a single transaction, I need all of them for a specific range. I've tried /admin/orders/transactions.json, or putting in all or * in for the id, and it returns errors unless the id is a valid transaction id. Any ideas?
Transactions belong to an order. So the ID you are wondering about is for one specific order. So if you want transactions for your accounting system, the important thing you're basing your API work on will be orders. So setup your code to first off download the orders of interest. Say for a month. Now for each order ask for the transactions, and produce your report.

Twitter Rest API: 404 No user matches for specified terms

Twitter allows up to 100 user ids at a time to query for user profile information. But if there is an invalid ID among those, it returns:
404 (Not Found), No user matches for specified terms
without specifying which is the bad ID and no data is returned for the rest of the users in the list. This happens if a user in the list closes their account.
Is there a way to identify the invalid ID without going through the list once again one by one (and possibly hitting the rate limit)?
https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-lookup.html
If a requested user is unknown, suspended, or deleted, then that user will not be returned in the results list.
If none of your lookup criteria can be satisfied by returning a user object, a HTTP 404 will be thrown.
From my understanding this means:
If you request 10 userIds and 1 of them is suspended, the request should still return 9 results
If you request 2 userIds and all of them are suspended, the request will return that error
I did a quick test and it seems to work as described.
Could it be that all of the IDs in your request are invalid?
You can use puts command for printing user id on first loop and you can see your log file or console to get the user id which is invalid.