Which routes to pick for REST API? [closed] - api

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I'm developing a restful API using NodeJS. To give you a little more insight in my application:
My application has surveys. A survey contains questions which in their turn has choices.
To add a question, you need to provide the id of the survey in the body of the post. To add an option, you need to provide the id of the question.
Now for the API routes. What would be better:
Option 1
/api/departments
/api/surveys
/api/questions
/api/choices
Option 2
/api/departments
/api/departments/department_id/surveys
/api/departments/department_id/surveys/survey_id/questions
/api/departments/department_id/surveys/survey_id/questions/question_id/options
The last one seems more logical because I don't need to provide the id of the parent in the body of the post.
What is best practice to use as endpoints?

I don't think there's a "best practice" between the two; rather, it's about having the interface that makes the most sense for your application. #2 makes the most sense if you're typically going to access the surveys on a per-department basis, and also makes sense in terms of accessing questions on a per-survey basis. If you wanted to eliminate the per-department part, you'd do something that's kind of a mix of the above:
/api/departments
/api/surveys
/api/surveys/survey_id/questions
/api/surveys/survey_id/questions/question_id/options
If you DO want to go by per-department, I'd change #2 so that instead of /api/departments/surveys one would access /api/departments/department_id/surveys ...
But without knowing more about the application, it's difficult to know what the best answer is.

Do surveys contain anything besides questions? do questions contain anything besides choices? The reason I ask is that if the answer to both is no then I'd actually prefer something like this:
/api/departments/ # returns a list of departments
/api/departments/<survey-id>/ # returns a list of questions
/api/departments/<survey-id>/<question-id>/ # returns a list of choices
/api/departments/<survey-id>/<question-id>/<choice-id> # returns a list of options
or something to that effect. Basically, I like to keep the concept of "containers" and "data" rigid. I like to think of it like a file system.
So if the concept ends in an "s", it's a container (and I'd like the route to end with a "/" to indicate that it acts like a folder, but that's a nit).
Any access to "/" results in the element at that index, which of course can be another container. Similar to directory structure in a file system. For example, if I were to lay these out in a file system, I might come up with something like this:
+ /api/departments/
|-----------------/human-resources/
|---------------/survery-10/
|----------/choice-10

The choice depends on whether resources are owned or shared by higher-level resources; whether you want cascading delete or not. If owned (with cascading delete), choose option 2 and if shared, choose option 1.
If a survey is deleted, I guess you want to delete all questions and options with it (cascading delete). This matches well with option 2, because if you delete resource /api/departments/departmentid/surveys/surveyid, you naturally also delete all subresources /api/departments/departmentid/surveys/surveyid/questions/....
On the other hand, if you want the option to share questions among multiple surveys and share surveys among multiple departments, then option 1 is better.
Of course, you can also have a mix of option 1 and option 2, if some resource types are owned and others are shared.

Related

Resource modelling in a REST API ( problems with timeseries data& multiple identifiers) [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I have some trouble modeling the resources in a domain to fit with a REST API. The example is obviously contrived and simplified, but it illustrates 2 points where I'm stuck.
I know that:
a user has pets
a pet has multiple names - one by each member of the family
a pet has: a date of birth, a date of death and a type (dog,cat...)
I need to be able to query based on dates (actually the date, or range of dates is mandatory when asking about pets). E.g.: tell me what pets I have now; tell me what pets grandma says we had 5 years ago until 3 years ago.
How should I handle dates?
a. in the query string: /pets/dogs/d123?from=10102010&to=10102015 (but as I understand, query string is mostly for optional parameters; and date/range of dates is needed. I was thinking of having the current date as default, if there's nothing in the query string. Any thoughts on this?)
b. somewhere in the path. Before /pets? This seems a bit weird when I change between a date and a range of dates. And my real path is already kind of long
How should I handle multiple names?
The way I see it, I must specify who uses the name I'm searching for.
/pets/dogs/rex -> I want to know about the dog called rex (by whom, me or grandma?). But where to put grandma?
I've seen some people say not to worry about the url, and use hypermedia But the way I understood that(and it's possible I just got it wrong) is that you have to always start from the root (here /pets )and follow the links provided in the response. And then I'm even more stuck(since the date makes for a really really long list of possibilities).
Any help is appreciated. Thanks
What might be useful in such scenarios is a kind of resource query language. It don't know the technology stack that you use, but a JavaScript example can be found here.
Absolutely do not put any dates in the path. This is considered as a bad style and users may be confused since, they most of them may be not used to such strange design and simply will not know how to use the API. Passing dates via query string is perfectly fine. You can introduce a default state - which is not a bad idea - but you need to describe the state (e.g. include dates) in the response. You can also return 400 Bad Request status code when dates range is missing in request. Personally, I'd go for default state and dates via query string.
In a such situation the only thing that comes to my mind is to reverse the relation, so it would be:
/users/grandma/dogs/rex
or:
/dogs/rex/owners/grandma
What can be done also is to abandon REST rules and introduce new endpoint /dogs/filter which will accept POST request with filter in the body. This way it will be much easier to describe the whole query as well to send it. As I mentioned this is not RESTful approach, however it seems reasonable in this situation. Such filtering can be also modeled with pure REST design - filter will become a resource as well.
Hypermedia seems not the way to go in this particular scenario - and to be honest I don't like hypermedia design very much.
You can use the query string if you want, there is no restriction about that. The path contains the hierarchical, while the query contains the non-hierarchical part, but that is not mandatory either.
By the queries I suggest you to think about the parameters and about what will be in the response. For example:
I want to know about the dog called rex (by whom, me or grandma?)
The params are: rex and grandma and you need dogs in the response.
So the hyperlink will be something like GET /pets/dogs/?owner=grandma&name=rex or GET /pets/dogs/owner:grandma/name:rex/, etc... The URI structure does not really matter if you attach some RDF metadata to the hyperlink and the params e.g. you can use the https://schema.org/AnimalShelter vocab. Ofc. this is not the best fit, because it does not concern about multiple names given by multiple persons, but it is a good start to create your own vocab if you decide to use RDF.

Should a REST API select on a ID or a name field? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I'm designing a REST API and trying to decide which is the more correct way of returning a single resource:
/resource/{id}
or
/resource/{name}
The ID would be immutable, so I'm thinking that it would be better to select by it, but name would be more friendly looking. What is the best practice? I've seen both used before "in the wild".
Basically REST is built on top of unique IDs, thus:
GET /resources/{id}/
should be used. However, there's nothing that prevents you from making name field unique (now it behaves as plain old ID) and build REST on top of this unique ID.
If this is not what you need and name cannot be made unique, then another option is to implement filtering via name:
GET /resources?name=<SOME_NAME>
It also should be resources (plural) since it indicates that there's a collection under the hood.
Whether using name instead is practical comes down to your business case.
Will 'name' always be unique? Or will the application deal with there being more than one occurrence?
Are 'pretty' URLs important? In most applications I've worked on, querying uses unique IDs which are never exposed to the end-user, as they have no business meaning whatsoever. They are in effect surrogate primary keys.
/resource/{id} is more technically correct, but if it were me, I'd allow both. Assuming names can't contain ONLY numbers, and ids can ONLY be numbers, you could easily detect which was supplied and allow for either to be used. ;)
This is good question .. it depends on business case example if api is used through cli like docker then you might want to use user friendly ids like name
But as soon as it become part of URL it has limitations like ASCII (to avoid url encoding or loss of readability ) char only and some defined length like 128 chars etc.

Database Design For Users\Downloads [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I need to design a database for something like a downloads site . I want to keep track of users , the programs each users downloaded and also allow users to rate+comment said programs.The things I need from this database - get average rating for a program , get all comments for a program , know exactly what program was downloaded by whom(I dont care how many times each program was downloaded but I want to know for each users what programs he has downloaded),maybe also count number of comments for each program and thats about it(it's a very small project for personal use that I want to keep simple)
I come up with these entities -
User(uid,uname etc)
Program(pid,pname)
And the following relationships-
UserDownloadedProgram(uid,pid,timestamp)
UserCommentedOnProgram(uid,pid,commentText,timestamp)
UserRatedProgram(uid,pid,rating)
Why I chose it this way - the relationships (user downloads , user comments and rates) are many to many . A user downloads many programs and a program is downloaded by many users. Same goes for the comments (A user comments on many programs and a program is commented or rated by many users). The best practice as far as I know is to create a third table which is one to many (a relationship table).
. I suppose that in this design the average rating and comment retrieval is done by join queries or something similar.
I'm a total noob in database design but I try to adhere to best practices , is this design more or less ok or am I overlooking something ?
I can definitely think of other possibilities - maybe comment and\or rating can be an entity(table) by itself and the relationships are between 3 entities. I'm not really sure what the benefits\drawbacks of that are: I know that I don't really care about the comments or the ratings , I only want to display them where appropriate and maintain them(delete when needed) , so how do I know if they better become an entity themselves?
Any thoughts?
You would create new entities as dictated by the rules of normalization. There is no particular reason to make an additional (separate) table for comments because you already have one. Who made the comment and which program the comment applied to are full-fledged attributes of a comment. The foreign keys representing these relationships (which are many-to-one, from the perspective of the comment table) belong right where you've put them.
The tables you've proposed are in third normal form which is acceptable according to best practices. I would add that you seem to be tracking data on a transactional basis (i.e. recording events as and when they occur). That is a good practice too because you can always figure out whatever you want to based on detailed information.
Calculating number of downloads or number of comments is a simple matter of using SQL Aggregate Functions with filters on the foreign key(s) that apply to your query - e.g. where pid=1234 etc.
I would do an entity for Downloads with its own id. You could have download status, you may have multiple download of the same program for one user. you may need to associate your download to an order or something else,..

College/University list for populating an Auto-complete field? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 8 years ago.
Improve this question
I'm trying to create an auto-complete text field with a list of known Universities and Colleges. Do you know where I can get this sort of list? Or is there a public API that contains this data?
I've found that IPEDS (Integrated Postsecondary Education Data System) is probably the most authoritative source for this data (and tons more related to it), and it's easy to export.
That page has a bunch of different tools for exporting different sets of the data in various common ways, but they all wrap around the "Download Custom Data Files" tool which is the most basic.
For a list (rather than data on a single institution), you would go to that custom data file page, and click on "By Group" to select the actual filters to use to limit what list of institutions you want (and what year of datasets). Then you click "Search", and it will provide a sample list of your results. From there, you click "Continue" to select which variables you want in the report with each of the institutions you've already filtered down to.
There's tons of variables, but in this case, you'll find everything you need under "Institutional Characteristics" most likely. Once you've selected all of the columns of information you want, click the big "Continue" button up top. You will then be presented with a bunch of download links for your data in a few various formats including CSV.
For quick results, try http://ope.ed.gov/accreditation/GetDownloadFile.aspx - it has complete data sets ready to download with all the key information.
The US Federal Aid Application site (http://www.fafsa.ed.gov/) has a very complete list, although I'm not sure how many non-US universities are listed (some are).
You could consider starting an application and scraping the list.
After a few moments of review, I'm pretty sure that fafsa doesn't want that list used by the public or make it easily accessible to the public.
If you go to their school search form (https://fafsa.ed.gov/FAFSA/app/schoolSearch?locale=en_EN) it uses autocomplete to provide the filtered data. I didn't feel like looking for too long at the script to see if I could figure out a URI that might give the entire listing, but I'm pretty sure they don't want people using their bandwidth. I will continue looking elsewhere. I'll try to post back if I find something more like what we're looking for.
...I'm back. I found dbpedia.org as a possible source (for this & MUCH more). I also tweaked an example to list all it's universities in alphabetical order and saved the html output for my own use.
I also found
http://infochimps.com/search?query=universities
this site apparently only "deals" with datasets (some free, some not)
I'm still hoping to find a "straight up" web resource that I can ping with queries for JSON.
ahhhh what'ya gonna do!?!? 8)
You might try the Department of Education: http://www.ed.gov/developer Data is available by API call or as csv. About to build the same experience using the API endpoint so I'll update with notes.

What mysql database tables and relationships would support a Q&A survey with conditional questions? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I'm working on a fairly simple survey system right now. The database schema is going to be simple: a Survey table, in a one-to-many relation with Question table, which is in a one-to-many relation with the Answer table and with the PossibleAnswers table.
Recently the customer realised she wants the ability to show certain questions only to people who gave one particular answer to some previous question (eg. Do you buy cigarettes? would be followed by What's your favourite cigarette brand?, there's no point of asking the second question to a non-smoker).
Now I started to wonder what would be the best way to implement this conditional questions in terms of my database schema? If question A has 2 possible answers: A and B, and question B should only appear to a user if the answer was A?
Edit: What I'm looking for is a way to store those information about requirements in a database. The handling of the data will be probably done on application side, as my SQL skills suck ;)
Survey Database Design
Last Update: 5/3/2015
Diagram and SQL files now available at https://github.com/durrantm/survey
If you use this (top) answer or any element, please add feedback on improvements !!!
This is a real classic, done by thousands. They always seems 'fairly simple' to start with but to be good it's actually pretty complex. To do this in Rails I would use the model shown in the attached diagram. I'm sure it seems way over complicated for some, but once you've built a few of these, over the years, you realize that most of the design decisions are very classic patterns, best addressed by a dynamic flexible data structure at the outset.
More details below:
Table details for key tables
answers
The answers table is critical as it captures the actual responses by users.
You'll notice that answers links to question_options, not questions. This is intentional.
input_types
input_types are the types of questions. Each question can only be of 1 type, e.g. all radio dials, all text field(s), etc. Use additional questions for when there are (say) 5 radio-dials and 1 check box for an "include?" option or some such combination. Label the two questions in the users view as one but internally have two questions, one for the radio-dials, one for the check box. The checkbox will have a group of 1 in this case.
option_groups
option_groups and option_choices let you build 'common' groups.
One example, in a real estate application there might be the question 'How old is the property?'.
The answers might be desired in the ranges:
1-5
6-10
10-25
25-100
100+
Then, for example, if there is a question about the adjoining property age, then the survey will want to 'reuse' the above ranges, so that same option_group and options get used.
units_of_measure
units_of_measure is as it sounds. Whether it's inches, cups, pixels, bricks or whatever, you can define it once here.
FYI: Although generic in nature, one can create an application on top of this, and this schema is well-suited to the Ruby On Rails framework with conventions such as "id" for the primary key for each table. Also the relationships are all simple one_to_many's with no many_to_many or has_many throughs needed. I would probably add has_many :throughs and/or :delegates though to get things like survey_name from an individual answer easily without.multiple.chaining.
You could also think about complex rules, and have a string based condition field in your Questions table, accepting/parsing any of these:
A(1)=3
( (A(1)=3) and (A(2)=4) )
A(3)>2
(A(3)=1) and (A(17)!=2) and C(1)
Where A(x)=y means "Answer of question x is y" and C(x) means the condition of question x (default is true)...
The questions have an order field, and you would go through them one-by one, skipping questions where the condition is FALSE.
This should allow surveys of any complexity you want, your GUI could automatically create these in "Simple mode" and allow for and "Advanced mode" where a user can enter the equations directly.
one way is to add a table 'question requirements' with fields:
question_id (link to the "which brand?" question)
required_question_id (link to the "do you smoke?" question)
required_answer_id (link to the "yes" answer)
In the application you check this table before you pose a certain question.
With a seperate table, it's easy adding required answers (adding another row for the "sometimes" answer etc...)
Personally, in this case, I would use the structure you described and use the database as a dumb storage mechanism. I'm fan of putting these complex and dependend constraints into the application layer.
I think the only way to enforce these constraints without building new tables for every question with foreign keys to others, is to use the T-SQL stuff or other vendor specific mechanisms to build database triggers to enforce these constraints.
At an application level you got so much more possibilities and it is easier to port, so I would prefer that option.
I hope this will help you in finding a strategy for your app.