Batch operations with access permissions on /classNotebooks and children endpoints - batch-processing

I need to perform complex batch operations with permission entities, for example, next business logic is required for my application to do:
1) Split a list of students onto a set of random lists with same size
2) Create a section group for each group, that means:
2.1) Remove all permissions that are not 'Owner'
2.2) Create permissions for the students that are in this group
As you can see, the process might be quiet complicated for leaving it to be performed on the app-side, but the official docs say nothing about batch delete based on OData queries or something like that.
So the question is next: is there any way to simplify kind of these algorithms using some batch-update/delete/create operations of the OneNote API ?
Thx in advance.

Yes, there is a way to batch operations with the OneNote API via OData batching - it is only supported in beta (for now) - all of the requests you make can be collapsed into one request and executed in batch in the server. This should work for your scenario.
http://odata.github.io/odata.net/04-08-client-batch-operations/
Essentially, you need to make a multipart request to our server with each of your requests in each part. You'll get a multipart with each of the responses.

Related

Restrict access of partial implmented API in Production

We need to develop an API which takes a CSV file as an input and persists them in database. Using vertical slicing we have split the reuirement into 2 stories
First story has partial implementation with no data validation
Second story completes the usecase by adding all validations.
Sprint-1 has first story and sprint-2 has second. After imlemneting first story in sprint-1 we want to release it to production. However, we dont want to make the API accessible to public which would be big security risk as invalid data could be inserted into database (story1 ignores validation)
What is the best strategy to release story1 at the end of sprint1 while addressing such security concerns?
We tried disbling the access via toggle flag such as ConfigCat. However, we dont want to implment something which is not required for actual implementation
is there really such a risk that in 1 sprint, someone may start using the API? And if you haven't added it to any documentation, how would they know of it's existance?
But let's say it is possible - what about using a feature toggle? When the toggle is activated, the end point spits out null or even a HTTP error code. Then you can enable to feature toggle when you're ready for people to start using the endpoint.

Azure QnA Maker - add multiple URLs through REST API

I have a working QnA Maker instance, I manually added a few URLs to public websites.
Now I want to add many more URLs. I guess this means mastering the REST API? What method should I call? Any examples to start from?
I found this sample, which got me started:
https://learn.microsoft.com/en-us/azure/cognitive-services/QnAMaker/quickstarts/create-new-kb-python
It's an example of calling the REST API's "Knowledgebase - Create" operation.
https://learn.microsoft.com/en-us/rest/api/cognitiveservices/qnamaker/knowledgebase/create
It crashes if you add more than 10 URLs. Eventually, I found there are limits of 10 URLs on create.
Adding more requires a separate REST call - "Knowledgebase - Update" with an "add" node in the request body.
https://learn.microsoft.com/en-us/rest/api/cognitiveservices/qnamaker/knowledgebase/update
I think this is limited to 5 URLs per call. I extended the python code to loop over my list of URLs and "add" them all. It seems to work but gets slower and slower to complete each call. My guess is QnA Maker re-runs some internal indexing logic over the whole knowledge base on every update call? If so then that limit per call is probably counter-productive.

How to build REST API with server-defined ids?

This is a classic RESTful way of creating resources I have in the application:
# This creates user. Client is responsible to create UUID, which is simple
PUT /users/CLIENT_GENERATED_UUID
# Access user by uuid
GET /users/UUID
When we touch the field of data storage performance it turns out that randomly generated UUIDs do not serve well by many reasons like data locality.
Server-generated IDs are good for performance but they don't really match REST:
If you use POST to create resources, you lose idempotency: PUT, GET, DELETE idempotency is implied by REST, while POST is not.
You may ask server to provide you with a nice ID before doing PUT. Despite it feels quite heavy and non-obvious, it also does not protect from dummy client that uses own random id instead of asking for it.
Could somebody give me a hint in this architecture matter?
Creating a resource using is not meant to be idempotent. If the server assigns the ID, it must choose a different ID for every resource to be created. Such an operation must not be idempotent, repeating it must create a different resource.
Using POST against a collecton resource as in
POST /users
is totally RESTful if the server assigns the ID. This request can be repeated and it will create a different resource.
Using an idempotent operation like PUT for creating a resource only makes sense if the problem domain allows the client to control the ID. I think that is ist not true for most domains.
My advice: use POST and let the server assign the ID.
Actually when you read RESTful Best Practices you can find that:
The POST verb is most-often utilized for creation of new resources.
in addtion to:
PUT can also be used to create a resource in the case where the resource ID is chosen by the client instead of by the server.
In REST environment you send POST to create resources and can return the server generated ID to send the values after with PUT or PATCH.
POST /users
PUT /users/id
Also, people create resources with PUT using client generated IDs
PUT /users
But I think the best aproach is use server generated IDs with POST.
Here are a clear explanation: http://www.restapitutorial.com/lessons/httpmethods.html

Hybrid REST + stateless operations in an API

I'm implementing a RESTful API for what is essentially a document store, but am hitting a brick wall because I need a hybrid approach to one of the operations that can be performed on these documents.
Essentially, a user should be able to generate PDF versions of documents that are stored as JSON but also generate PDF versions of JSON strings that are passed arbitrarily (with no record in the database). The PDF reports never need to be stored anywhere, they are always generated on the fly.
My current API looks like:
/Documents
/Documents/1234
/Documents/1234?rev=4
Now, one way to implement the PDF generation would be to do:
/Documents/1234/Reports
or
/Reports/1234
But since we don't need to store PDFs (generated on the fly), both are reduced to only a GET operation, and it doesn't really act on a 'Report' object - which doesn't seem RESTful to me.
What complicates it further is that a user should be able to manually pass a JSON blob to the service and get a PDF. So something like:
/API/GeneratePDF
So does a separate stateless API make sense for this one operation? Maybe then redirect a request like /Reports/1234 to /API/GeneratePDF with the JSON blob for the 1234 document. It all seems a bit messy :)
The URL '/reports/123/' is pointing to a 'report' resource and it should not matter what backend operations will be acted on it.
When thinking about resource-url and its associated operations, the only relevant operations are "GET/PUT/POST/DELETE"
Then map the business operations (like generate PFD report) to the url+HTTP-Op+params.
Like in this case, map 'generate PDF report" to "GET /reports/123/"
use-case-1: simple get report
GET /reports/123/
return: {pdf-report}
use-case-2: customized report
GET /reports/123/
param: {"json info passed along with the get operation"
return: {pdf-report}
The the backend can detect if there are input from the client to decide what specific backend operations should be taken to generate the report.
Hope this help!

How to authenticate, filter, and verify WCF-based oData result?

Can someone tell me if it's possible to do this with my WCF-based oData feed, and let me knlow what to search for or how to get started?
1) Authenticate - I'd like to make sure that the oData service is only accessed by someone who has already authenticated using the ASP.NET membership system
2) Filter - Suppose I'm returning a list of student classes... I'd like to make it so that students only see classes they enrolled in (based on username) and not the ones for that haven't yet been published.
3) Verify - I'm not sure if this is needed, but just in case some clever hacker finds a hole in MSFT's oData protocol, I'd like to verify the results of my Entity Framework data prior to streaming to the client. This would apply if there is a singleton DAL, thus creating concurrency issues. See 5:15 of this video for an example.
The test I want to do is verify that every row returned has a username column that equals the current session username.
[EDIT]
4) Encrypt - This is similar to #3, but I'd like to obfuscuate the primary key before it is sent to the client. In one case, the PK is the social security number and I don't want that being cached, or otherwise sent downstream. I would need to decrypt this on an oData write as well.
1) Authentication - as mentioned by Coding Gorilla above there's a series of posts on the WCF Data Services blog on how to implement different kinds of authentication.
2) Filter - this is exactly what query interceptors are for. See for example this article on MDSN http://msdn.microsoft.com/en-us/library/dd744837.aspx
3) Verify - if you think you really need to this, it might be a bit tricky. Currently WCF Data Services doesn't have an extensibility point which you could plugin easily to see the results being written out. You might be able to wrap the IQueryable instances returned by EF and do the verification when the results are enumerated, but I haven't seen that done yet, so don't know if it will work.
4) This will be tricky just in WCF Data Services. I would try to do this inside EF alone (not sure if it's possible though). The problem is that the key properties are used to address the entities, so they show up in URLs and queries. So you would not only need to decrypt them in the payloads but also in the query itself which would be a lot of work. Maybe somebody with more EF experience will know how to do this in EF alone (in which case WCF Data Services would see just the encrypted values and everything would work)