How should I design my RESTful API in this case? - api

I've got a DB with a lot of people of type (PLAYER, DOCTOR, TEACHER) where each person has an ID and location ID. There're some common fields like first name, last name but also some fields that are specific on person's occupation: number of injuries / the most serious injury type for PLAYER, number of patients for DOCTOR and can_teach_math for TEACHER.
I want to build an API to compute total compensation of all these people that accepts a list of IDs (optional), list of location IDs (optional). For example, if someone passes 3 personIDm API should return a response with an array where each row corresponds to a specific person. If someone passes locationIDs - API should return all people who are living in that area.
Originally, I was thinking I could just return people ID:
request = {..., person_id:[person-123, person-456], location_id = [location-1, location-2]}
response = {
[person_id:person-123, first_name=Alex, compensation=100],
[person_id:person-456, first_name=Alex2, compensation=102],
# anyone who lives in location-1, location-2
[person_id:person-13, first_name=Alex3, compensation=50],
[person_id:person-12, first_name=Alex4, compensation=52],
}
However UI engineer showed up and said they want to see
also some fields that are specific on person's occupation: number of injuries / the most serious injury type for PLAYER, number of patients for DOCTOR and can_teach_math for TEACHER.
in a response even though it makes API denormalized. That said, it makes sense to me since loading all the object info through GET persons/{ID} might take quite a long time. Without going too much of the details, let's see we don't care about speed -- is the proper way to design RESTful API is not to return
also some fields that are specific on person's occupation: number of injuries / the most serious injury type for PLAYER, number of patients for DOCTOR and can_teach_math for TEACHER.

Related

What is the industry standard way to store country / state / city in a database of web APP?

For country and state, there are ISO numbers. With City, there is not.
Method 1:
Store in one column:
[Country ISO]-[State ISO]-[City Name]
Method 2:
Store in 3 separate columns.
Also, how to handle city names if there is no unique identifier?
First and foremost, three separate columns to keep your data. If you want to create a unique identifier, the easiest way would be giving a random 3-10 digit code depending on the size of your data set. However, I would suggest concatenating [country-code]-[state-code]-[code] if you have a small data set and if you want human readability to a certain point. code can be several things. Here are some ideas:
of course a random id or even a database row id
licence plate number/code if there is for a city
phone area code of the city or the code of the center
same logic may apply to zip codes
combination of latitude and longitude of the city center up to certain degree
Here are also more references that can be used:
ISO 3166 is a country codes. In there you can find codes for states or cities depending on the country.
As mentioned IATA has both Airport and City codes list but they are hard to obtain.
UN Location list is a good mention but it can be difficult to gather the levels of differentiation, like the airport code or city code or a borough code can be on the same list, but eventually the UN/LOCODE must be unique. (Airport codes are used for ICAO, similar to IATA but not the same)
there are several data sets out there like OpenTravelData or GeoNames that can be used for start but may require digging and converting. They provide unique codes for locations. And many others can be found.
Bonus:
I would suggest checking Schema.org's City Schema and other Place Schemas for a conscious setup.

Restrict Google Places API search by type

I am performing a query using Google Places API to search for local restaurants
https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=..lat,..lon&radius=..radius&type=restaurant&key=..key
However, I am receiving a lot of results for locations that are not primarily restaurants, for example:
Popular hotels with restaurants
Food delivery services
Night clubs
Department stores with dining
etc.
Ideally I would like to restrict my query to only a few types or prohibit certain types by query. Otherwise I would need to do this manually or find another service.
Just add the city name as a prefix in the search string. It will only give the search suggestions in which the user is searching.
eg, pass "NewYork" as a prefix in your search string, now type any word, it will only give you results for NewYork city restaurant, cafes, places, etc

Most appropriate way to store/retrieve User Input in a eCommerce iOS application?

I'm a bit confused with Sqlite, Core Data, NSUserDefaultsand PropertyList. I know what is what, but not a very clear idea of about where to appropriately use them.
I know that there are lots of tutorials, but I'm good at learning through situation based understanding. So kindly do help me to understand this in the situation that I'm facing right now and to make use of the available options wisely.
I'm working on an ECommerce iOS (native) application, where I'm highly dependent on API's for data display. Now I'm in need of recording user's review for a product and send it over through an API.
ie. I have three components, rating title, rating value(for that title) and another rating title ID. I'm defining with an example, I need to store multiple rows with details,
Components Data to be stored
**Title** - Quality | Value | Price
| |
**Rating** - 2 | 3 | 1
| |
**TitleID** - 10 | 11 | 12
Like this, there will be so many entries, i.e, the number of components differs for various users, for some users, there might be more than three components, which must be saved & send through an API. So how should I save these data? which is the RIGHT way to save these data temporarily?
If I understand you correctly, as vaibhav implied your question seems pretty general and probably relates more to structuring your data to fit your requirements than to technical aspects of the iOS / CoreData environment. In that vein, I’ll offer a few thoughts I’d have in structuring a data structure for quality ratings per your description.
If your ratings will always be for the three categories you show, i.e. Quality, Value and Price, I wouldn’t over-complicate things; I’d just use three properties in a rating record to hold the values that a user assigns in his/her rating of a product (just showing selected attributes and relationships in all following lists):
Product
name
Rating
ratedProduct (many to one)
qualityRating Int
valueRating Int
priceRating Int
Done this way you’d need to associate the values with their types in code for the APIs, such as (where item is a retrieved rating record):
display(product: item.ratedProduct.name, quality: item.qualityRating, value: item.valueRating, price: item.priceRating).
On the other hand, you may be describing a more generic approach that would allow for ratings categories that vary more frequently, or perhaps vary among products. This could apply where, for example, ratings include how well things fit for clothing but not for other products like books. In that case, you’d need a more complicated structure where a product could have a variable number of ratings of different types, so you’d need another layer of entities that let you create an arbitrary number of rating records that applied to a product.
Here you'd create a separate rating record for each rating that a user assigned to a product.
The simplest form of that structure would be like the following:
Product
name String
UserEvaluation
ratedProduct (many to one)
productRating (one to many)
ProductRating
ratingType (many to one)
value Int
RatingType
ratingTitle String
ratingID String or Int
Then you’d have to have a bit more structure where you'd list the product and then access the ratings with a loop that cycled through the set of all of the ratings linked to the product record somewhat like this (where item is a retrieved UserEvaluation):
displayTitle(product: item.ratedProduct.name)
for rating in item.productRating {
displayRating(ratingTitle: item.productRating.ratingType.title, ratingValue: item.productRating.value)
}
You'd probably want to combine these into a method that takes the name and an array of ratings.
To keep track of things, you’d also probably want to create another entity that defined product classes and specified what specialized ratings applied to each class (like fit for clothing and mileage for cars). By default, you also may want to allow for a few generic rating types that apply to all products (like the quality and price ratings you show). For this approach, the full structure would look like this:
Product Category
title
ratingType (many to many)
Product
productType (many to one)
UserEvaluation
ratedProduct (many to one)
productRating (one to many)
ProductRating
ratingType (many to one)
value Int
RatingType
ratingTitle String
ratingID String or Int
With this structure, once a product is assigned a productType, the application would know what ratings to ask for in the UI.
You could try building more complicated rating records with all of the types that apply to a product category, but that would get very messy if the applicable categories vary over time. You could also create a "custom" rating type that let a user specify a title and input a rating, in which case you'd need a text field in the rating record that only applies if the ratingType is "custom".
I hope this helps…

Will First Name + Last Name + Date Of Birth combination be unique enough?

I need help with the algorithms/ database design for my current working on web-based application (I apologize for the long question in advance)
Application description:
I am building a customer check-in station (it's basically just a monitor that displays a webpage and was connected to a scanner) where customers who come into an office (similar to a library) can scan their office ID card (it has an unique bar code on it) to check-in, customer information (First name, Last name, date of birth, check-in time...) will be sent/saved onto server and the office administrator will be able to see who is in the office right now and do stuff...)
When creating ID card for a new customer, the only information needed is: first name, last name and date of birth (customer can be any ages from kids to elder) => system will generate a unique bar-code (16 digits) and print out a new ID card (with only the bar-code on it)
Problem:
If a customer forgot/ lost their ID card or sometimes the card is too old so the bar-code can't be scanned, customer can type in their first+last name and date of birth into the check-in station then system will search for (first name + last name + date of birth) and determine whether that customer existing and check them in. But it is possible that there is more than one person who has same name + birthday:
- system then can display all matched people to screen but how can customer know which one is them self?
- or that situation can be avoided if system would not allowing customer who has same name and dob to be saved the to database in first place. But then the customer who came "second" will be very upset that he/she can not have a card :))
Edit:
How do I deal with this problem, I mean this is just a office so we can not ask for SSN or driver license ... the check-in process have to be simple and quick some of them maybe a kids who don't have any ID or phone (they will come with their parents/guardians) and many of them are older people (older than 70, or even 80) they can't even type that why the "ID card - scanning idea is here to help them - all they need to do is scan their card... (I don't think they ever can remember the "security question"), SMS verify will not work (phone number may be changed, not all of customer have a phone, the carrier will be involved here (coverage, rate charge...) I don't want any of that ).
OK after read all your suggestion:
I am thinking about a 4 digit pass-code (like 3 digits security code in the back of a credit card) - it will be printed out in the ID card with the instructions and everything, this will be different from the unique customer number (used to scan), here how it works:
- when creating a new customer ID card, system will ask for an additional 4 digits pass-code and also print it out to the card, an algorithms also will be put there to make sure that customers who have same name + dob can't have same pass-code.
In case customer can't use/lost the card, after they entering name+dob to check-in, system only ask this 4-digit passcode if there are more than 1 matched person, otherwise if there is only 1 person matched, system will check-in them in right on.
if they ever forgot this pass code, I mean there is nothing else they can do for them self, the receptionist will have to somehow help them, what do you guys think, I am still open for suggestions?
My final solution:
Because the cards have nothing else (of customer information) rather than the bar code (customer number) on it so the best way is to preprint (pre-made)them, have them ready in the desk to give to new customers or for card replacement purposes.
When creating a new customer, receptionist will manually input first name + last name + dob + phone number (optional) + email (optional) + home address + customer number (as same as in the card that they about to give to the customer) +. submit, system will check for everything, if everything is good receptionist then give customer a new card => customer come back to check-in station and check-in.
When customers forgot card => they will need to see the receptionist => do verification process => receptionist will check them in manually.
When customer lost card or card is damaged => they will need to see the receptionist => do verification process => receptionist then give customer a replacement card => customer come back to check-in station and check-in.
Have each customer tell you two "security question" style data: Location of birth, favorite dish, ... These can serve as uniquifiers.
You can then prevent duplicates from being entered because in case there is a colliding registration the customer must simply chose a different question.
Some rambling thoughts:
You could assign users a PIN and use that to make the account unique. Presumably to insure that it is unique you would have to assign it, you can't let them invent one. (You could let them invent one and then verify it's unique. That might be good to allow people to use numbers that have some meaning to them so they can remember them.) The big catch to this is that if the person loses his PIN, you're stuck. If the PIN is printed on the card, then if the card is damaged or worn, yes, they could type in the PIN. But if they lost the card, they might have no other record of the PIN.
You could ask for their phone number and use that as an identifier. My grocery store does that for their discount card. I think almost everyone has a phone these days. For the small number who don't, you could generate a random number that looks like a phone number but is not valid (so it won't coincidentally duplicate any real phone number), and use it like a PIN. For example if you're in the US, you could make generated numbers all start 555-555 and then make the last 4 digits be like a PIN. Then the only people who would be a problem are those who don't have a phone AND who lost their card, which should be a very small number.
Is there any information in this system that is confidential, or are people committing to spending money? I mean, if someone walked up to a kiosk and typed in the name and birth-date of his next door neighbor and accessed that person's account, would that be a problem? You haven't said what the system does. If getting into the system gives someone access to the person's medical records or bank account or transcripts of his last confession to his priest, then you have to take steps to prevent unauthorized access, you can't let just anyone come up and claim to be someone else and get in. I'm reminded of a case a few years ago where a reporter got access to records of some politician's DVD rentals. He was apparently hoping to find that he had rented a lot of vile pornography or some such that he could use to embarrass the guy, though as it turned out it was mostly westerns. My point is that even seemingly innocent information could be embarrassing to someone under the right circumstances, so you have to be careful.
How often do people have lost or damaged cards? And are there clerks available who could help someone in such cases? That is, if 99% of the time someone comes in, swipes his card, and he's in and everything is good, and the number of times that someone has a lost or damaged card is very small, you could say that in those cases they have to go to a clerk and show the damaged card, or if they say they lost their card, show identification. Then the clerk can verify whatever and give them a new card. You could have the clerk search by name and have a screen that shows birth dates and addresses, ask the customer what their birth date and address is and if it matches one, give them a new card, if not, say I'm sorry you're not on file. This is quite different from a security point of view of showing the customer the list of birth dates and addresses and letting them pick one, as a customer could, (a) type in a common or overheard name and then pick any matching entry that shows up, or even (b) use this to find the address of someone they want to harass, and then you could be liable.
On the current project I met the same way to find a customer. The project is about TV stuff, so the second level of 'sieve' is address. And I think you need to expand the customer information: a username, an email, an avatar or something easy to remember (or send a SMS with code). Also you can add user friendly behavior: if a customer cannot decide which record about him/her, the customer should go through the wizard and add needed information. Yes, it's hard to find a general evidence for all customers, but you can support several kinds of extra information.
In other words: first name, last name, and birth date aren't enough for unambiguously getting a person.

Phone books and databases : what's the best option?

I am currently working on a development project for which I need to make a database (I will be using Postgre).
Part of that database must store a phonebook for every company, and also for every user. Those two "types" of phonebook are stored in two tables, although they contain the same type of information :
PersonalPhoneBook(IdOwner, IdUser)
//Ids of the owner and a user he's in contact with.
CompanyPhoneBook(IdCompany, IdUser)
//Ids of the company and a user it's in contact with
The personal phonebook will be retrieved with a request like:
SELECT * F
ROM User
WHERE IdUser IN
(SELECT IdUser FROM PersonalPhoneBook WHERE IdOwner = x);
(this request isn't optimized, but you get the gist).
I should also mention that every user and company has as many details (phone numbers, addresses, ...) as they want, thanks to these three tables :
ContactDetail(IdContactDetail, LbContactDetail, ValueContactDetail)
Company_ContactDetail(IdCompany, IdContactDetail)
User_ContactDetail(IdUser, IdContactDetail)
Now there is something that I didn't take in count in that model : the users and companies will want to include in their phone books some people that aren't users in the database.
So I've been exploring several solutions, and I'd need advice to determine which is best:
Making two other tables to store a fixed number of details (2 phone numbers, 1 address) on those "outsiders".
Making all "outsiders" users (but I find that pretty ugly to store them together)
Store an independent phonebook (LDAP-type) for every company and every user (but then data is replicated)
Keep the contact detail system for companies and users and use a LDAP system for the others
Other...?