How to get status of only 1 lead in a program with GetLeadsByProgramID endpoint? - marketo

I am using the GetLeadsByProgramID REST API endpoint to get the Leads with Status under a Program in Marketo. But is there any way where I can get the status of only 1 lead for a program?

First, an advice:
As Marketo applies some limits for accessing the API (most importatntly: Daily Quota, Rate Limit, Concurrency Limit), it is considered to be a good practice to fetch as many records as you can with one API call and cache the results. You can allways loop through and filter out the result set as needed.
A solution:
With that said, you can still fetch the program status of one particular lead, but with not the GetLeadsByProgramID endpoint. Unfortunately that endpoint does not allow filtering based on lead Id.
The program status change of a lead is also an activity, and luckily there is an endpoint, Get Lead Activities to query just that. You need to have four things before making the call:
A paging token –obtained from the Get Paging Token endpoint–, that also defines the earliest datetime to retrieve activities from.
The Id of the “Change Status in Progression” activity type, which can be gathered from the Get Activity Types endpoint. It is 104 in my case, but this is not guaranteed to be the same in all instances.
The Id of your Lead object in question. I assume you have that on record.
The Id of the Program you checking statuses for. I guess you have that on record too. It can be fetched via the API too, but that is also present in the url when you click on the program in your instance. E.g.: if your link is https://app-abc01.marketo.com/#ME1234A1, the Program Id is 1234.
So, having all that info at hand you can make the call as described at the Activities Endpoint Reference page. In essence this is the url you have to call:
GET /rest/v1/activities.json?nextPageToken=<YOUR_NEXPAGE_TOKEN>&activityTypeIds=104&leadIds=<LEAD_ID>&assetIds=<PROGRAM_ID>
The response will contain all the program status changes of the Lead in the given Program after the given datetime. So you still might need to perform a loop in case there are multiple status changes.
You can decide if all this worth the effort.

Related

Return entity updated by axon command

What is the best way to get the updated representation of an entity after mutating it with a command.
For example, lets say I have a project like digital-restaurant and I want to be able to update a field on the restaurant and return it's current state to the client making the update (to retrieve any modifications by different processes).
When a restaurant is created, it is easy to retrieve the current state (ie: the projection representation) after dispatching the create command by subscribing to a FindRestaurantQuery and waiting until a record is returned (see Restaurant CommandController)
However, it isn't so simple to detect when the result of an UpdateCommand has been applied to the projection. For example,
if we use the same trick and subscribe to the FindRestaurantQuery, we will be notified if the restaurant has been modified,
but it may not be our command that triggered the modification (in the case where multiple processes are concurrently issuing
update commands).
There seems to be two obvious ways to detect when a given update command has been applied to the projection:
Have a unique ID associated with every update command.
Subscribe to a query that is updated when the command ID has been applied to the projection.
Propagate the unique ID to the event that is applied by the aggregate
When the projection receives the event, it can notify the query listener with the current state
Before dispatching an update command, query the existing state of the projection
Calculate the destination state given the contents of the update command
In the case of (1): is there any situation (eg: batching / snapshotting) where the event carrying the unique ID may be
skipped over somehow, preventing the query listener from being notified?
Is there a more reliable / more idiomatic way to accomplish this use case?
Axon 4 with Spring boot.
Although fully asynchronous designs may be preferable for a number of reasons, it is a common scenario that back-end teams are forced to provide synchronous REST API on top of asynchronous CQRS+ES back-ends.
The part of the demo application that is trying to solve this problem is located here https://github.com/idugalic/digital-restaurant/tree/master/drestaurant-apps/drestaurant-monolith-rest
The case you are mentioning is totally valid.
I would go with the option 1.
My only concern is that you have to introduce new unique ID associated with every update command attribute to the domain (events). This ID attribute does not have any Domain/Business value by my opinion. There is an Audit(who, when) attribute associated to every event already, and maybe you can use that to correlate commands and subscriptions. I believe that there is more value in this solution (identity is part of domain), if this is not to relaxing for your case.
Please note that Queries have to be extended with Audit in this case (you will know who requested the Query)

Whats the best way to generate ledger change Events that include the Transaction Command?

The goal is to generate events on every participating node when a state is changed that includes the business action that caused the change. In our case, Business Action maps to the Transaction command and provides the business intent or what the user is doing in business terms. So in our case, where we are modelling the lifecycle of a loan, an action might be to "Close" the loan.
We model Event at a state level as follows: Each Event encapsulates a Transaction Command and is uniquely identified by a (TxnHash, OutputIndex) and a created/consumed status.
We would prefer a polling mechanism to generate events on demand, but an asynch approach to generate events on ledger changes would be acceptable. Either way our challenge is in getting the Command from the Transaction.
We considered querying the States using the Vault Query API vaultQueryBy() for the polling solution (or vaultTrackBy() for the asynch Obvservalble Stream solution). We were able to create a flow that gets the txn for a state. This had to be done in a flow, as Corda deprecated the function that would have allowed us to do this in our Springboot client. In the client we use vaultQueryBy() to get a list of States. Then we call a flow that iterates over the states, gets txHash from each StateRef and then calls serviceHub.validatedTransactions.getTransaction(txHash) to get signedTransaction from which we can ultimately retrieve the Command. Is this the best or recommended approach?
Alternatively, we have also thought of generating events of the Transaction by querying for transactions and then building the Event for each input and output state in the transaction. If we go this route what's the best way to query transactions from the vault? Is there an Observable Stream-based option?
I assume this mapping of states to command is a common requirement for observers of the ledger because it is standard to drive contract logic off the transaction command and quite natural to have the command map to the user intent.
What is the best way to generate events that encapsulate the transaction command for each state created or consumed on the ledger?
If I understand correctly you're attempting to get a notified when certain types of ledger updates occur (open, approved, closed, etc).
First: Asynchronous notifications are best practice in Corda, polling should be avoided due to the added weight it puts on the node for constant querying and delays. Corda provides several mechanisms for Observables which you can use: https://docs.corda.net/api/kotlin/corda/net.corda.core.messaging/-corda-r-p-c-ops/vault-track-by.html
Second: Avoid querying transactions from the database as these are intended to be internal to the node. See this answer for background on why to avoid transaction querying. In general only tables that begin with "VAULT_*" are intended to be queried.
One way to solve your use case would be a "status" field which reflects the command that was used to produce the current state. For example: if a "Close" command was used to produce the state it's status field could be "closed". This way you could use the above vaultTrackBy to look at each state's status field and infer the action that occured.
Just to finish up on my comment: While the approach met the requirements, The problem with this solution is that we have to add and maintain our own code across all relevant states to capture transaction-level information that is already tracked by the platform. I would think a better solution would be for the platform to provide consumers access to transaction-level information (selectively perhaps) just as it does for states. After all, the transaction is, in part, a business/functional construct that is meaningful at the client application level. For example, If I am "transferring" a loan, that may be a complex business transaction that involves many input and output states and may be an important construct/notion for the client application to manage.

how GET method is idempotent

How GET method is idempotent and POST is not. we are using it in form submission, if we submitting it twice it will re-submitting the form data's. And why we are not using GET for order placing or purchasing products for instance when it is idempotent.
An idempotent HTTP method is a HTTP method that can be called many times without different outcomes. It would not matter if the method is called only once, or ten times over. The result should be the same. Again, this only applies to the result, not the resource itself.
a=10; //This is idempotent: no matter how many times we execute this statement, a will always be 4.
a++; //This is not idempotent. Executing this 10 times will result in a different outcome as when running 5 times.
Now, coming to your query.
If we use GET method for order placing/purchasing products, the order will be placed no matter the product is gone out of stock. In contrast if you use the to POST method the result will be different for each new request made for purchasing product.
Below example is not idempotent because for every new request the outcome will be different
https://accounts.google.com/Login#identifier
The GET method should be used to send the information from the browser to the server in the URL. Below is an example usage of GET method.
http://www.google.co.in/search?q=cristiano+ronaldo
Below is the answer to your query in the comments:
When users revisit a page that resulted from a form submission, they might be presented with the page from their history stack (which they had probably intended), or they might be told that the page has now expired. Typical user response to the latter is to hit Reload.
This is harmless if the request is idempotent, which the form author signals to the browser by specifying the GET method.
Browsers typically will (indeed "should") caution their users if they are about to resubmit a POST request, in the belief that this is going to cause a further "permanent change in the state of the universe", e.g. ordering another Mercedes-Benz against their credit card or whatever. If users get so accustomed to this happening when they try to reload a harmless idempotent request, then sooner or later it's going to bite them when they casually [OK] the request.
Now, while implementing those two methods GET and POST, a developer should consider the security issues and write the code in the particular method. Any code can be written in both the methods considering all the limits of GET method(size of url etc.), But this is not a good practice.
GET -> for information retrieval.(If you want to read data without changing state)
POST -> for information creation/updation/deletion.

Get all leads programmatically in Marketo v1

I would like to get all the leads that a customer has in Marketo.
I understand that you can Get Multiple Leads by Filter Type REST API endpoint.
If I do not have access to their Marketo UI, how should I get all the leads?
I was thinking about querying 300 ids at a time until there were no more results. But I am unsure about how to handle if all leads in a 300 batch are deleted, but there are leads after that deleted batch. Are deleted leads returned?
I'll describe a workaround you can use to determine the last lead that was created in Marketo using the REST API. You can use this lead as the upper bound for lead id, and then query leads 300 at a time until you reach this upper bound as you described.
The workaround is to use the Get Lead Activities API to return activities for most recent leads that were created. By calling this API, you can determine the last lead that was created in Marketo, and then use it as your upper bound.
Here are some tips for calling the Get Lead Activities API:
Specify an activityTypeIds=12 parameter to return
activities for new leads.
Include a paging token parameter as the start date to
look for the most recent leads that were created. To generate a paging token, you will need to use
the Get Paging Token API.
To optimize this, start with a time range that is close to the
current date. For example, first query the Get Lead Activities API
for leads created in the past hour. Then if there are no results,
query for the past day, and so on.
Iterate through the results from the Get Lead Activities
API until the moreResult attribute in the response is false. The last
lead returned will be the upper bound for leads ids.
For example, a call to the Get Lead Activities API will look like:
/rest/v1/activities.json?nextPageToken=GIYDAOBNGEYS2MBWKQYDAORQGA5DAMBOGAYDAKZQGAYDALBQ&activityTypeIds=12

How to create a RESTful object with server calculated fields

I have an object:
Account
{
Id,
Name,
CurrentBalance
}
Id is an immutable key, Name is a mutable string, and CurrentBalance is calculated from all of the transactions associated with the account.
I am stuck on the fact that GET \Accounts\{Id} will not be idempotent because changes to a transaction will cause a change in CurrentBalance. Should I remove this field from the object and make a request like
POST \Accounts\{Id}\CurrentBalance
But now I have to make multiple calls to the server to get the CurrentBalance of all objects:
GET \Accounts
POST \Accounts\{Id1}\CurrentBalance
POST \Accounts\{Id2}\CurrentBalance
POST \Accounts\{Id3}\CurrentBalance
....
I guess I am just looking to see if there is already a standard way to handle this that I am missing?
UPDATE
Part 2 if the original object is ok via GET. My only way to update the Account.Name is via a PATCH as I cannot allow an update to CurrentBalance, correct?
NOTE
I realize I could put this on the client to have to get all transactions and calculate it, but I would prefer to do this on the server for multiple reasons
Idempotency does not mean that you must always get the same response back.
Consider the resource /TodaysWeather. It would be pretty useless if it always returned the same value.
Idempotency simply states that if a client makes the same request multiple times instead of just once, the impact on the system (from the client's perspective) will be the same.
I just re-read the HTTP specs and realized that if I want to be truly RESTful I have to make multiple calls because GET has to be safe.
In particular, the convention has been established that the GET and
HEAD methods SHOULD NOT have the significance of taking an action
other than retrieval.
I am not deleting this question because I think it could help others in the future, but if the majority disagree I will delete it
If it's important that you're able to PUT some data, then immediately retrieve the same data via GET, then you could simply treat it as a different resource entirely, e.g.:
# Change an account name
PUT \Accounts\{id}
# Get accounts/names/balances
GET \AccountDetails
# Get balance of an account
GET \AccountDetails\{id}\CurrentBalance
However, there's really no good reason to go through the trouble of doing that. Your PUT is idempotent as long as making the same request multiple times doesn't change the state of the system. Not changing the system's state if some spurious value is submitted is the correct behavior. In fact, if someone does try a PUT including CurrentBalance, you might want to return a 400 (Bad Request) status explaining that CurrentBalance can't be updated.

Resources