What is the difference between clientContext.Site and clientContext.Web when using the Client Object Model?
site returns an SP.Site object (called "Site Collection" in non-API documentation) and web returns an SP.Web object (called "Site" in non-API documentation). The web's Site is the same as site.
Different operations can be performed upon the different hierarchical objects. Either the Site or the Web will be required depending upon operation (the operations are exposed by the API) - that's all.
See Overview of Sites (aka "SP.Web") and Site Collections (aka "SP.Site") in SharePoint - for how the two different types relate.
Related
I am planning to have these endpoints for our REST APIs.
PUT /tenant/:tenantId/users/save/:username
POST /tenant/:tenantId/users/invite
GET /tenant/:tenantId/users/fetch
GET /tenant/:tenantId/users/fetch/:username
PATCH /tenant/:tenantId/users/activate/:username
POST /tenant/:tenantId/groups/save/
Verbs such as save/fetch/activate are from the consistency point of view. Are these RESTFul according to the REST principles? How should these be changed if at all? Any recommendations?
According to this REST Resource Naming Guide:
RESTful URI should refer to a resource that is a thing (noun) instead of referring to an action (verb) because nouns have properties which verbs do not have – similar to resources have attributes.
And also
URIs should not be used to indicate that a CRUD function is performed. URIs should be used to uniquely identify resources and not any action upon them. HTTP request methods should be used to indicate which CRUD function is performed.
So let's take your first URI as example
PUT /tenant/:tenantId/users/save/:username
Here you are using the verb save. As mentioned before you should not be indicating a CRUD operation in the URI, in this case using a POST would be more appropriate.Here is a guide with the purpose of each HTTP verb. Knowing this, I think that for example a more appropriate URI for that case would be something like
POST /tenants/:tenantId/users/:username
In this cases:
GET /tenant/:tenantId/users/fetch
GET /tenant/:tenantId/users/fetch/:username
you should remove the fetch because you are already telling through the GET verb that data is being fetched. Same goes for the 6th example.
But, this doesn't mean that you can't use verbs in your URIs, in fact there is a specific category called controller which as mentioned in the same guide:
A controller resource models a procedural concept. Controller resources are like executable functions, with parameters and return values; inputs and outputs.
Use “verb” to denote controller archetype.
This controllers resources could go well (I asume) with for example your
GET /tenant/:tenantId/users/activate/:username.
But I would think that the verb activate should go last:
GET /tenant/:tenantId/users/:username/activate
First note: REST doesn't care what spelling conventions you use for your resource identifiers. Once you figure out the right resources, you can choose any identifiers for them that you like (so long as those identifiers are consistent with the production rules defined in RFC 3986).
"Any information that can be named can be a resource" (Fielding, 2000), but its probably most useful to think about resources as abstractions of documents. We use HTTP as an application protocol whose application domain is the transfer of documents over a network.
GET
This is the method we use to retrieve a document
PATCH
PUT
POST
These methods all indicate requests to edit a document (specifically, to edit the request target).
PUT and PATCH are each ask the server to make its copy of a document look like the client's local copy. Imagine loading a web page into an editor, making changes, and then "saving" those changes back to the server.
POST is less specific; "here's a document that we created by filling in a web form, edit yourself appropriately". It is okay to use POST: after all, the web was catastrophically successful and we're still using POST in our form submissions.
The useful work is a side effect of these edits.
Are these RESTFul according to the REST principles?
Do they work like a web site? If they work like a web site: meaning you follow links, and send information to the server by submitting forms, or editing the webpages and submitting your changes to the server, then it is REST.
A trick though: it is normal in REST that a single method + request uri might have different useful side effects. We can have several different HTML forms that all share the same Form.action. Uploading changes to an order document might have very different effects if the edits are to the shipping address vs to the billing information or the order items.
Normal doesn't mean obligatory - if you prefer a resource model where each form request goes to a specific resource, that can be OK too. You get simpler semantics, but you support more resources, which can make caching trickier.
I am trying to figure out the "right" implementation for an url structure for an application with multitenancy support and shared resources.
Resources: Users, Projects
The URL schema is
host/api/tenant_id/resource[/id][/subresource][/id]
User A (width id = 1) gets a collection of his projects at
GET http://example.com/api/1/projects/
User A creates a new project, readable by
GET http://example.com/api/1/projects/2
Now User A gives another User B (id = 2) access to project 2.
User B would like to see a collection of all projects related to his account via:
GET http://example.com/api/2/projects/
Should the shared project (id = 2) be in this collection besides those, User B created by himself? Or is there a better naming structure for shared resources?
Focusing on the design of URL structures is actually a no-go for RESTful architectures. Roy Fielding:
A REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server).
See also this answer.
For your specific problem I would return a list of (basically arbitrary) hypertext links to the projects the user has access to. The links would contain attributes making it clear, whether the project is »owned« or »accessible« by the user. To improve readability you could design your resource URLs as
http://example.com/user/{user id}
http://example.com/project/{project id}
The representation of user after a GET http://example.com/user/2 would contain the list of links like
<a href="http://example.com/project/1" class="owned"/>
<a href="http://example.com/project/2" class="access-permitted"/>
The HATEOAS principle is inherent to REST and makes most »how do I design my URIs« questions obsolete:
The principle is that a client interacts with a network application entirely through hypermedia provided dynamically by application servers. A REST client needs no prior knowledge about how to interact with any particular application or server beyond a generic understanding of hypermedia.
Maybe one advantage can be in using tenant info in the path. In such way we can easily have for example the lists of objects.
Querying the uri on get /tenant-id/projects
We can have a list of of projects for each entry tenant.
How can be get without tenant info into url?
My 2 cents
I want to create a content type, lets call it MyDocument with some properties we need. However we have 10 departments each one with its own site collection.
I want all documents to be created using MyDocument,across all site collections.
Thanks
In SharePoint 2010, you can use a Content Type Hub.
From Plan to share terminology and content types:
To share content types among site collections, you make one content type gallery the “hub” of a managed metadata service, create connections to the service from each Web application that contains a site collection, and specify that site collections should use the content types in the service.
The same effect can also be achieved using a custom Feature.
I'm creating an app that will be configurable by the end-user to access SharePoint lists, on various different SharePoint sites, that are entered by the user.
All of the examples for reading SharePoint lists I've come across online are of the form:
Open or create a Visual Studio
project.
In Solution Explorer,
right-click the References node, and
then click Add Service Reference.
In the Address box, type the URL to
the target site and append
/_vti_bin/ListData.svc. For example,
the address for the site
intranet.wingtip.com would be
http://intranet.wingtip.com/_vti_bin/ListData.svc.
Change the default name in the
Namespace box from ServiceReference1
to something more appropriate, such
as WingtipSite.
etc, etc, etc
This method creates proxy classes within your project based on the specified server reference. However, in my case, the server/site is not known at design time, only runtime by reading the sites/lists specified by the user. How would one go about doing that (reading the list via http://intranet.wingtip.com/_vti_bin/ListData.svc, but at runtime only)?
Note: I am making this call from a different machine than the one running Sharepoint.
There are a couple answers.
If the lists schemas will be consistent across all the sites you are querying, you can still use the generated proxy. When you create the DataContext, you just need to pass in the URI to the ListData.svc for the site chosen by the user.
If not, then you can use an ASP.NET WebRequest with an appropriately formatted URI and parse out the ATOM or JSON response that comes back.
For more information on using the REST APIs, check out this talk from the 2009 SharePoint Conference
http://msdn.microsoft.com/en-us/sharepoint/ff462048
You can set the URL in your proxy class at runtime with the Url property.
SharePoint does not provide a proxy class for their web services. Therefore it's not possible to set the url at runtime. WHat I have had to do is add 2 service references and then paramaterize which one I will access. I use a config setting to determine which one to access. If the site name changes or list changes, then I need to remove the references, re-add them, recompile and redeploy. There is no way to change the SharePoint site/list at runtime. Have been searching for 3 days for an answer. Microsoft does not know how to accomplish this.
Is it possible to get an OOTB PortalSiteMapProvider to provide a site heirarchy from a specified site collection or URL (i.e. not the current site collection) in SharePoint 2010? In MOSS this was only possible by creating a custom SiteMapProvider, traversing the site collections and manually building the navigation tree.
NB: I am not prepared to write a
custom SiteMapProvider that reads from
a static XML (.sitemap) file as the regular site contributors may not have access to files on the file system.
A little bit of background... I have a single web application with 2x site collections:
1 for my intranet portal at http://intranet/ (publishing enabled)
1 for the My Sites at http://intranet/my (publishing not enabled)
We have no plans to facilitate multiple portals, therefore, I would like a consistant global navigation bar across both site collections. Ideally, I'd like the My Sites to show the site heirarchy from the main portal site. So is it possible to set the PortalSiteMapProvider.CurrentSite property to "http://intranet/" instead of "http://intranet/my"?
To achieve this behaviour I wrote my own web service which goes off and traverses another site collection's hierarchy (using it's own PortalSiteMapProvider), and returns that structure as an XML document. I obviously then bound my global navigation navigation menu to that.
I got the concept from here: PortalSiteMapProvider
There is a similar approach describes here which uses HttpHandlers instead: http://blog.symprogress.com/2011/03/sharepoint2010-custom-navigation-provider-cross-sitecollection/