Restful resource naming for "secondary" tables - rest

Let's go with my example, I have 3 tables and I want to know what's the best method to name my resource url.
Tables:
building
building_type The most simple to define is #1.
API resources:
GET someapi.com/buildings
GET someapi.com/**?**
My problem is that I don't know what's the best practice for "secondary tables" like building_type.
Maybe:
GET someapi.com/buildings/types
GET someapi.com/building-types
...
I hope some of you will reach to enlighten me. Thanks.

You first need to figure our the requirements for your API, the scenarios, use cases etc, and only then actually start building it.
To go back to your question, I'd go for GET someapi.com/buildingTypes, because /buildings/types will leave you with a "Types" resource which doesn't make much sense on it's own. You could indeed make it so it's only accessible once you go to the buildings resource, so GET someapi.com/buildings/buildingTypes could be the way to navigate to it.

Related

Google MyBusinessInformation API, where are the services?

I'm stuck with the BusinessInformation API, actually I can add custom categories and services bound to it in the Google MyBusiness interface, but I'm still trying to figure out how to do the same using the API.
So far I found the way to get all the categories here, but I'd like to only get the categories that are bound with my current location.
Then about the services bound to each category, I couldn't figure it out what I only got similar is that link but it's deprecated.
Does someone know the way to do this?
Best
Sorry for this, actually it's OBVIOUS: those are attributes of the Location object.
I'll leave this here though, just in case that someone falls in the same trap.

Rest API design: Managing access to sub-entities

Note: I realize that this is close to being off-topic for being opinion-based, but I am hoping that there is some accepted best practice to handle this that I just don't know about.
My problem is the following: I need to design a Rest API for a program where users can create their own projects, and each project contains files that can only be seen by users that have access. I am stuck with how to design the "List all files of a project" query.
Standard Rest API practice would suggest two endpoints, like:
`GET /projects` # List all projects
`POST /projects` # Create new project
`GET /projects/id` # Get specific project
etc.
and the same for the files of a project.
However, there should never be a reason to list all files - only the files of a single project. To make it more complicated, access management needs to be a thing, users should never see files that are in projects they don't have access to.
I can see multiple ways to handle that:
So the obvious way is to implement the GET function, optionally with a filter. However, this isn't optimal, since if the user doesn't set a filter, it would have to crawl through all projects, check for each project whether the user has access, and then list all files the user has access to:
GET /files?project=test1
I could also make the files command a subcommand of the projects command - e.g.
GET /projects/#id/files
However, I have the feeling this isn't too restful, since it doesn't expose entities directly?
Is there any concencus on which should usually be implemented? Is it okay to "force" users to set a parameter in the first one? Or is there a third alternative that solves what I am looking for? Happy about any literature recommendations on how to design this as well.
Standard Rest API practice would suggest two endpoints
No, it wouldn't. REST practice would suggest figuring out the resources in your resource model.
Think "documents": I should be able to retrieve (GET) a document that describes all of the files in the project. Great! This document should only be accessible when the request authorization matches some access control list. Also good.
Maybe there should also be a document for each user, so they can see a list of all of the projects they have access to, where that document includes links to the "all of the files in the project" documents. And of course that document should also be subject to access control.
Note that "documents" here might be text, or media files, or scripts, or CSS, or pretty much any kind of information that you can transmit over the network. We can gloss the details, because "uniform interface" means that we manage them all the same way.
In other words, we're just designing a "web site" filled with interlinked documents, with access control.
Each document is going to need a unique identifier. That identifier can be anything we want: /5393d5b0-0517-4c13-a821-c6578cb97668 is fine. Because it can be anything we want, we have extra degrees of freedom.
For example, we might design our identifiers such that the document whose identifiers begin with /users/12345 are only accessible by requests with authorization headers that match user 12345, and that all documents whose identifiers begin with /projects/12345 are only accessible by requests with authorization headers that match any of the users that have access to that specific project, and so on.
In other words, it is completely acceptable to choose resource identifier spellings that make your implementation easier.
(Note: in an ideal world, you would have "cool" identifiers that are implementation agnostic, so that they still work even if you change the underlying implementation details of your server.)
I have the feeling this isn't too restful, since it doesn't expose entities directly?
It's fine. Resource models and entity models are different things; we shouldn't expect them to always match one to one.
After looking further, I came across this document from Microsoft. Some quotes:
Also consider the relationships between different types of resources and how you might expose these associations. For example, the /customers/5/orders might represent all of the orders for customer 5. You could also go in the other direction, and represent the association from an order back to a customer with a URI such as /orders/99/customer. However, extending this model too far can become cumbersome to implement. A better solution is to provide navigable links to associated resources in the body of the HTTP response message. This mechanism is described in more detail in the section Use HATEOAS to enable navigation to related resources.
In more complex systems, it can be tempting to provide URIs that enable a client to navigate through several levels of relationships, such as /customers/1/orders/99/products. However, this level of complexity can be difficult to maintain and is inflexible if the relationships between resources change in the future. Instead, try to keep URIs relatively simple. Once an application has a reference to a resource, it should be possible to use this reference to find items related to that resource. The preceding query can be replaced with the URI /customers/1/orders to find all the orders for customer 1, and then /orders/99/products to find the products in this order.
This makes me think that using solution 2 is probably the best case for me, since each file will be associated with only a single project, and should be deleted when a project is deleted. Files cannot exist on their own, outside of projects.

Problem with the contacts endpoint regarding "related_contacts"

I have a problem with the contacts endpoint regarding related_contacts.
I'm trying to make this request:
https://app.clio.com/api/v4/contacts.json?fields=id,name,first_name,last_name,type,primary_email_address,primary_phone_number,is_client,activity_rates{rate,flat_rate},addresses{name,street,city,province,postal_code,country},custom_field_values{id,field_type,field_name,value,custom_field},phone_numbers{name,number,default_number},web_sites{name,address,default_web_site},account_balances{name,type,balance},related_contacts{id,type,name,first_name,last_name,primary_email_address,primary_phone_number,is_client},primary_work_address{name,street,city,province,postal_code,country},company{id,type,name,first_name,last_name,primary_email_address,primary_phone_number,is_client},payment_profile{id,name,terms,discount_rate,discount_period,interest_rate,interest_period,interest_type},co_counsel_rate{id,rate,flat_rate,contact_id,co_counsel_contact_id},primary_web_site{name,address,default_web_site},created_at,updated_at&type=Company&client_only=true&order=name(asc)&limit=200
But it fails. If I remove the related_contacts{} part, it works. If I add back so much as related_contacts{id} it fails.
Has anyone else run into this?
I don't think this exactly answers your question, but I've been struggling with the same thing and as best I can tell, related_contacts is a dead-end in the API.
The real answer I think is not to use related_contacts at all, instead use the relationships endpoint. If you log on to the Clio portal and look at "Related contacts" under matter, this is actually the call that it's making.
You could call all relationships as you calling all contacts in your sample, but it's probably much more useful to include either the matter_id or contact_id as part of the query string to get relationships specific to one or the other.

How to define URI for types of a certain resource

Currently, I have an API for showing a list of spots using this route: GET /spots
I also have an API which gets the details for a certain spot: GET /spots/{spot-id}
Now, I will be making another API, which shows all the categories of the spots. Do you guys know of a proper way to go about with this?
So far I have decided on using GET /spots/categories but my manager said it was kind of weird for the spots resource to have categories.
His current suggestions are GET /spot-categories and GET /spotcategories.
Also, for reference, I have database tables spot and spot_category.
Thank you!
I tend to agree with your manager, your spotcategories look like a different entity altogether, so as a resource it deserves a separate url. That being said, if the goal is to find the categories for a particular spot (as opposed to simply browsing through the different available spotcategories), you should only be able to navigate to them through the spots (presuming your API is on level 3 of the Richardson Maturity Model). As in a link from the spots to the categories (or simply embed them, depending on the usage requirements).
So you might end up with something like
GET /spots/{spot-id}/categories

Best practice for updating a structured resource via REST?

I have a client-side interface that allows the user to perform multiple edits against a tree-like outline. I consider the aggregate of the records making up that outline, in totality, a single resource (/outlines/39) even though its parts could be accessed as separate resources via different URLs.
The problem is the user can edit existing nodes in the outline as well as add new nodes to the outline. Normally, when you edit something you PUT its changes and when you add something new you POST it; however, in some cases you'll want to wrap all the changes--including both adds and edits--in a single transaction. What are some practical ways people have handled this?
Even though the outline already exists and a PUT seems appropriate, the embedded adds violate the idempotence of the PUT. I'm not sure that POST seems appropriate either. For design purposes, I have decided not to save each discrete update the user makes though I guess this offers one solution. Still, there must be others who have dealt with my issue or have ideas about it.
Is there any way you could make the add idempotent? E.g. if nodes had a natural key, then when the client tried to add a node a second time you could do nothing.
How about: make a new resource: /outlines/39/transactions, and POST your transaction to that resource, e.g.
POST "addNode=node1, addNode=node2, editNode=node3,newName=foobar" to /outlines/39/transactions