I want to build my first API using Apigility v1.1. It will be a "private" API (consumer must be auhorized through the OAuth2 to use the API). I've already read the tutorial and seen some examples, but I haven't found anything regarding to requests throttling. I want to limit the number of requests to 50 requests per login per one minute.
Does Apigility support requests throttling? And if not, where I should implement it (controller or somewhere else)? It would be nice if the throttling would be done before controller's action is called.
Check my answer https://stackoverflow.com/a/32392608/949273
Basically is the similar thing.
You will create listener attached to ZF2 Event MvcEvent::EVENT_ROUTE and on every request (before any controller) execute your logic - check no. requests and return appropriate status/message or let user execute request.
Related
I'm looking for some advice about authorization for a request I'm making in Power Automate Desktop using the action 'Invoke Web Service'. I'm using this request to get information from Dataverse.
I've currently set up this request using OAuth2.0 with the Grant Type set to Implicit and I've hardcoded a token value into the header. I'm pretty green when it comes to authorization, so I'm just wondering if that's the best way to use OAuth2.0 to get info from Dataverse to PAD? I'm also concerned this token will expire and how to go about handling that. If I should set this up differently please let me know. And if you know how I can refresh the token automatically somehow, advice would be great.
I'm going to make the assumption that you have an Azure instance within your org.
You should be able to execute the entire OAuth flow through PAD given you can do it through Postman ...
https://learn.microsoft.com/en-us/powerapps/developer/data-platform/webapi/use-postman-web-api
... having said that, if you want an easier way, my suggestion would be to use LogicApps as it does all of the hard work for you. It will also protect keys, etc. that run the risk of being exposed if contained within a PAD flow and that's even if your store that sort of information in a KeyVault or something. At some point, it needs to be exposed to PAD.
You can create a LogicApp that's triggered by an incoming HTTP request ...
... and have your DataVerse connector pull the relevant data ...
... to then return back to the calling PAD flow with a response action.
This is an example flow ...
I haven't gone into detail given your question lacks specifics around filtering, etc. but you can always make your LogicApp more comprehensive by adding functionality in the payload to order, filter, expand, etc. on the OData call to DataVerse so you get exactly what you want from a data perspective.
I have a Rails API which can handle requests from the clients. Clients use that API to perform analysis of their data. Client POSTs the data to API, API checks if that data have been analysed before. If so API just respond with analysis result. If the data haven't been analyzed before API:
Tells client that analysis started.
Establishes the connection with analyzing microservice.
Performs asynchronous (or deferred or i don't know) request to the analyzing microservice and waiting for response. The analysis takes much time so neither the API nor the microservice should be blocked while doing it.
When the response from analyzing microservice is returned API hands it to the client.
The main issue for me is to set up things such way that client could receive somehow the message "Your data had been sent to analysis" right after he performed the request. And then when analysis will be done client could receive its result.
The question is what approach I have to use in that case? Async responses, deferred responses, something else? And what known solutions could help me with that? Any gems?
I'm new to that stuff so I'm really sorry if I ask dumb questions.
If using HTTP you can only have one response to every request. To send multiple responses, i.e. "work in progress", then later the "results", you would need to use a different protocol, e.g. web sockets.
Since HTTP is so very common I'd stick with that in combination with background jobs. There are a couple of options which spring to mind.
Polling: The API kicks off a background jobs (to call the microservice) and responds to the client with a URL which the client can ping periodically for the result. The URL would respond with some kind of "work in progress" status until the result is actually ready). The URL would need to include some kind of id so the API can lookup the background job.
The API would potentially have two URLS; /api/jobs/new and /api/jobs/<ID>. They would, in Rails, map to a controller new and show action.
Webhooks: Have the client include a URL of its own in the request. Once the result is available have the background job hit the given URL with the result.
Either way, if using HTTP, you will not be able to handle the whole thing within a request/response, you will have to use some kind of background processing (so request to the microservice happens in a different process). You could look at Sidekiq, for example.
Here is an example for polling:
URL: example.com/api/jobs/new
web app receives client request
generates a unique id for the request, SecureRandom.uuid.
starts a background job (Sidekiq) passing in the uuid and any other parameters needed
respond with URL such as example.com/api/jobs/
--
background job
sends request to microservice API and waits for response
saves result to database with uuid
--
URL: example.com/api/jobs/UUID
look in database for UUID, if not found respond that job is "in progress". If found return result found in database.
Depending on what kind of API you use. I assume your clients interact via HTTP.
If you want to build an asynchronous API over HTTP the first thing that you should do: accept the request, create a job, handle it in the background and immediately return.
For the client to get the response you have to 2 options:
Implement a status endpoint where clients can periodically poll the status of the job
Implement a callback via webhooks. So the client has to provide a URL which you then call after you're done.
A good start for background processing is the sidekiq gem or more general ActiveJob that ships with Rails.
We have existed API like
/api/activiation_code
each time, the activiation_code will be different, then server will create a token for this call and return it, usually each call will have different activiation_code which return different token.
Since this API need server to create something so it is designed as POST.
Can we design this API as HTTP GET ?
What is the pro and cons ?
You could design the API to support GET requests, but I would not recommend this. If your API is accessible via a website, a user could accidentally activate an account multiple times since the URL will be stored in the browser's history. Additionally, web crawlers could potentially supply values to your API through the URL if you support GET requests.
POST requests are much better because the information is included in the body of the request, not the URL. Thus, it is much less likely that something will go wrong accidentally.
The Gmail iOS API under the hood appears to be creating 'POST' requested with a payload that specifies an action. So for example if I want to get a single message by ID, I would expect (at least since the documentation on the API specifies it) that I would create a GET request with the correct URL schema. Instead the Gmail iOS implementation does not and utilizes more of an RPC approach. Unfortunately this means all POST requests have a default timeout of 240 seconds and cannot be changed, apparently an iOS bug/weird implementation. I can create a timer and cancel the request but why not make the implementation RESTful?
Yes, this is a quark with the Google iOS client libraries in general--they do not follow the standard REST semantics of the APIs like all the other client libraries use. I imagine due to some limitation in iOS. In any case, https://code.google.com/p/google-api-objectivec-client/ would be the best place to read more about it, discuss and file bugs. (Not specific to the gmail-api.)
The library was written to create JSON-RPC requests because those have always supported a batch request model. A mechanism for batch REST requests was added much later to Google's JSON API servers.
The timeout issue on POSTs was resolved in iOS 6, according to discussions online like this.
The project site does have links to the library's discussion group and issue tracker.
I want to fetch location of person and connections so how should I specify fields for this purpose?
http://api.linkedin.com/v1/people/~/network/updates:(update-content:(person:(id,headline,location)))?type=CONN
If I'll make another calls for just getting location, it will be very costly for me, as it will require to make extra calls for each of new connection and will increase number of calls exponentially. So, I want some solution using which I can get location in network updates API call itself.
EDIT: And another thing I need is to check about the privacy setting of connections. As per my knowledge, linkedin doesn't provide any api which returns that which connection allows to see updates and which are not. So, when I try to get network update for a particular connection, it returns error that this user doesn't allow public to see updates. If I want to check this thing before call network updates API, how can I do it in Ruby Language.
OR
Let me know some way to pass multiple dynamic IDs while calling linkedin API.
When retrieving person data associated with a Network Update, it appears that only the basic fields are available. The solution would be to get the id for the person and make a second call to the Profile API:
http://api.linkedin.com/v1/people/id=12345:(first-name,last-name,connections,location)
Currently, linkedin doesn't provide any API for this purpose. You have to make multiple calls for this purpose. But you should make these calls in chunks to avoid timeout issues.
Reference
Try this api
`String url = "https://api.linkedin.com/v1/people/~/connections:(id,first-name,last-name,location,picture-url,positions:(title,company:(name)))"; `