customer/charities endpoint not returning email field - paypal

The api documentation for the charities endpoint specifies that one of the fields returned in the response is the "email" field. https://developer.paypal.com/api/limited-release/charity-search/v1/#definition-charity_response
However, when calling the API, I am not seeing this field getting returned. I know that this field exists, because I can filter results based on the email field by using https://api.paypal.com/v1/customer/charities?email=blah#gmail.com. This will correctly filter results for charities that I know the emails of.
To hit this API at all you need a username and password. I'm thinking maybe the username/password I have does not have sufficient permissions to view this field? Or perhaps something else is going on?

Related

REST API best practices: ignoring filter when empty

In the scenario of a users API (/api/users) with a property of team_id, I want to set up an endpoint that allows me to get users with specific team IDs, i.e. /api/users?team_ids=1&team_ids=2&team_ids=3.
My question is, what if I want to ignore this filter?
For instance, if there's a multiselect dropdown in the UI and the user de-selects all team_ids, the expected result would be nothing as they have selected zero teams, and all users are in a team. From an API perspective however, I think it would be reasonable to expect that /api/users would return all users.
You can simply make that parameter required then, so if it doesn't exist the response is an empty array. Or you can limit the amount of users returned

Should I allow user-provided values to be passed through a query string?

I'm adding a search endpoint to a RESTful API. After reading this SO answer, I'd like the endpoint to be designed like:
GET /users?firstName=Otis&hobby=golf,rugby,hunting
That seems like a good idea so far. But the values that I'll be using to perform the search will be provided by the user via a standard HTML input field. I'll guard against malicious injections on the server-side, so that's not my concern. I'm more concerned about the user providing a value that causes the URL to exceed the max URL length of ~2000 characters.
I can do some max-length validation and add some user prompts, etc, but I'm wondering if there's a more standard way to handle this case.
I thought about providing the values in the request body using POST /users, but that endpoint is reserved for new user creation, so that's out.
Any thoughts? Thanks.
I see these possible solutions:
not actually a solution. Go with the query parameter and accept the length constraints
go with the POST solution that shouldn't be designed as you mention. As you point out, if you POST a user to .../users you will create a new user entity. But this is not what you want to do. You want to submit a search ticket to the server that will return a list of results matching your criteria. I'll design something as such
POST .../search/users passing in the body a representation of your search item
distribute the query both server side and client side. Say you have complex criteria to match. Set up a taxonomy of them so that the most strict ones are handled server side. Thus, the server is able to return a manageable list of items you can subsequently filter on the client side. In this approach you can save space in the query string by sending to the server only a subset of the criteria you want to meet in your search.

How can I verify a Paypal account registered under a business name using GetVerifiedStatus?

I am successfully using Paypal's Adaptive Accounts API's GetVerifiedStatus endpoint to verify our users' Paypal accounts by first name, last name, and email address. However, a significant fraction of them use Paypal business accounts which don't have a first and last name associated (or else they did provide one and have forgotten it.)
Is there a special way to e.g. enter business name in the "first name" field? Or do all accounts have a first/last name associated and our users need to look that up? Thanks!
Update to clarify: I'm aware that setting matchCriteria to NONE in the request theoretically allows one to perform an email-only search. However, Paypal enables this on a case by case basis, and we haven't been granted NONE status, thus must use NAME which per the docs requires first and last.
I've been playing around with this and found a way to make the call without having to set the option to matchCriteria=NONE. If you make the call by placing the business name twice, both in the first name and last name field, you should be able to get a successful reply from the API.
Looking at the API and playing around with the API explorer, you've got two options.
Set matchCriteria to NONE
In this case sending the first name and last name to the API is optional and the validation will only use the email address.
Set matchCriteria to NAME
In this case sending the first name and last name to the API are required and the validation will use the email address, the first name and last name fields.
You can verify the setting by using the playground, e.g. using test#example.com and any random names.
In your case I would provide the email address, first name and last name as input fields and set matchCriteria to NONE and send the request to the API.

What is the best way to design REST URI for nested resources

Say there are users having multiple authorizations having multiple permissions.
Retrieving all authorizations for the specified user (without permissions) could be:
GET users/{id}/authorizations
The "normal" case is to not embed permissions with authorizations for performance reason.
There are cases when authorizations must be returned with their respective permissions for that user.
Suggested solutions are:
GET users/{id}/authorizations/permissions // does not seem clear
GET users/{id}/authorizations?permissions=true // with query string
GET users/{id}/authorizationswithpermissions // new resource
Now what is the best way to design the REST URI in that case?
Your ideas
There are cases when authorizations must be returned with their respective permissions for that user.
GET users/{id}/authorizations/permissions
It is not a good idea to nest collection resource like this. Does it mean "give me all permissions of all authorizations of user id"? This is unclear. Don't do this.
GET users/{id}/authorizations?permissions=true
A query is normally used to query, search, or filter on a collection resource. This URL woud return all authorizations for user id for which permissions is true. But what does that man? This is unclear. Don't do this.
GET users/{id}/authorizationswithpermissions
Authorizations are authorizations. Their representation should not depend on the URI. Don't do this.
Content Negotiation
The solution to your problem is to use content negotiation. You only use one URL:
GET users/{id}/authorizations
This means: Give me a list of all authorizations of user id.
Now if you want to get this list without permissions, you could use the HTTP header
Accepts: application/vnd.mycompany.authorizations+xml
Let's digest this.
application: the first part of the normal MIME type application/xml
vnd: a prefix to define your own type
mycompany.authorizations: your type
xml: the second part of application/xml
Now if you want to get this list with permissions, you could use the HTTP header
Accepts: application/vnd.mycompany.authorizations.permissions+xml
Note that me now use vnd.mycompany.authorizations.permissions. The server should return the authorizatons including the permissions. Only the representations are different, not the resources.
Personnally I can't find any problem with both two last suggestions:
GET users/{id}/authorizations?permissions=true // with query string
GET users/{id}/authorizationswithpermissions // new resource
Except I would change them as follow to be more relevant:
GET users/{id}/authorizations?withPermissions=true // with query string
GET users/{id}/authorizationsANDpermissions // new resource
The first one seems to be quite confusing but your RESTful entities should be documented whatever notation you will opt for.

RESTful way to check availability of usernames, emails, etc

I've recently gotten very into trying to think as RESTfully as possible, and I'm finding myself stymied by the non-obvious routes.
In this particular case, I'm curious about the RESTful way to check for username and email availability for a user, or anything else that has uniqueness.
My gut tells me that I would want to perform a GET on /users/email or /users/username/ each with a required param, or something along the lines of GET /users/search/ with optional params of email and username. If you get a 200, then the username or email is unavailable; if you get a 404, then it's available.
I prefer the first option since it's more explicit, but it's not like I've pored over Roy Fielding's thesis to know well enough what to do.
What's the most sound approach here?
The first approach does seem to be more "RESTful". You try to GET a specific resource (by username or email) and get it if it exists or get a status message "unavailable resource". This would be:
GET /users/username/johnwayne (to "get" johnwayne resource/username availability...)
This should generate:
200: if resource exists
404: if the resource does not exist
The second one seems more like "SOAP"-like web service, where you define a "function" (/users/search/) with some "parameters" (username, email)...
For unique fields, first option is a good fit (/users/email or /users/username/), for non-unique fields search would be more appropriate.
i would recommend, you use HEAD request instead of GET.
Using a GET may pose a security problem. A hacker can use a combination to identify valid username as GET would either result in 200 or 404.
You should try to get a list of users with your mail by
GET /users?query=asd#gmail.com
And here you can find 1 item or 0 items. In first case the address isn't unique. In another - it's unique