Im trying to make coupa cxml orderrequest approval fail. Setting error code 400/401, but coupa still thinks the approval was successful, and the requisition changes status to ordered. Any ideas how to make coupa understand that approval wasn't successful?
So basically you are trying to reject a Purchase Requisition? If so- you need to send it to a different URL-->
/api/approvals//reject
The exchange of CXML between Coupa and supplier systems is pretty much hidden from the buyer. When they click Approve, the Order is queued up to be sent, perhaps minutes later, while the buyer sees a visual status change immediately. This means that inline validation and rejection doesn't work. Coupa will treat any status code other than 200 as a non-fatal error and will just keep trying to send the same thing.
The only thing you can really do is return a status code 200 to the order, then separately do your validation, and produce an order confirmation CXML to Coupa with "accept" or "reject" as appropriate, the latter of which will change the status of the order on Coupa side.
Related
If there is a limit on the number of resources created using POST request, what should be the status code?
Let's say, there is a restriction on the number of resources created using POST wherein only 10 resources can be created. The 11th POST request should fail due to the above constraint. What should be the status code?
Should it be 422 with a meaningful message, something along the lines of "Resource count limit reached"? or is there a status code for this?
It really depends on your use-case.
If user is limited in time (let's say 10 per day) but might actually get more credits later automatically, I suggest 429 Too Many Requests as client sent to many requests in one day.
If credits are locked (ie: User only had 10 free credits), I suggest 403 Forbidden as the request is fully understood and processable but the server does deny it due to lack of credits.
Anyway 422 Unprocessable entity is not correct as the request is well formed and server might process it with given credits. Nothing is really missing from the request (from what I understand from your post).
I think that HTTP400 is appropriate, especially if you can provide helpful feedback in the error response. If a user is submitting an invalid payload in the request- it's a bad request. Anything else might get confusing.
Though, HTTP405 (Not Allowed) might be better. If there are no POST more requests accepted by the server for a particular resource that may be more accurate. However it really just depends on the future use of the API.
I'm working on architecting a micro-service solution where most code will be C# and most likely Angular for any front end. My question is about message chaining. I am still figuring out what message broker to use; Azure Service Bus , RabbitMQ, etc.. There is a concept which I haven't found much about.
How do I handle cases when I want to fire a message when a specific set of messages have fired. An example but not part of my actual solution: I want to say Notify someone when pays a bill. We send a message "PAIDBILL"
which will fire off microservices which will be processed independently:
FinanceService to Debit the ledger and fire "PaymentPosted"
EmailService: email Customer Saying thank you for paying the bill
"CustomerPaymentEmailSent"
DiscountService: Check if they get a discount for paying on time then send
"CustomerCanGetPaymentDiscount"
If all three messages have fired for the Same PAIDBILL: Message "PaymentPosted", "CustomerPaymentEmailSent", "CustomerCanGetPaymentDiscount"
then I want to email the customer that they will get a discount on their next bill. It Must be done AFTER all three have tiggered and the order doesn't matter. How do I Schedule a new message to be sent "EmailNextTimeDiscount" message, without having to poll for what messages have fired every minute, hour, day?
All I can think of is to have a SQL table which marks that each one is complete (by locking the table) and when the last one is filled then send off the message. Would this be a good solution? I find it an anti-pattern for the micro-service & message queue design.
If you're using messages (e.g. Service Bus / RabbitMQ), then I think the solution you have described is the best one. This type of design - where services have knowledge about the other domains in the system - is typically known as choreography.
You'll want to pick a service which will be responsible for this business logic. That service will need to receive all the preceding types of messages so that it can determine when (if) all have been met, which it probably wants to do by recording which of the gates have already passed in a database.
One alternative you could consider is chaining the business processes instead of doing them in parallel. So...
PAYBILL causes FinanceService to Debit the ledger and fire "PaymentPosted"
"PayentPosted" causes EmailService to email Customer Saying thank you for paying the bill and broadcasts "CustomerPaymentEmailSent"
"CustomerPaymentEmailSent" causes DicsountService to check if they get a discount for paying on Time then sends "CustomerCanGetPaymentDiscount"
The email you want to send is just triggered by "CustomerCanGetPaymentDiscount".
If I'm honest, I would switch around the dependency model you're using at this last stage. So, instead of some component listening for "CustomerCanGetPaymentDiscount" events from DiscountService and sending an email, I think I would instead have the DiscountService tell some other component to send an email. It seems natural to me for something that calculates discounts to know that an email should be sent. It seems less natural for something that sends emails to know about discounts (and everything else that needs emails sent). This is why I don't like architectures where the assumption is that every message should be an event and every action should be triggered by an event: it removes a lot of decisions about where domain logic can live, because the message receiver always has to know about the domain of the message sender, never vice versa.
So they've clicked the unsubscribe link in a newsletter. In their profile it says, for example:
This person unsubscribed on Mar 24, 2017 2:40 pm
After receiving "Newsletter Test#6"
Great, but how can I tell programmatically, via the API, if someone has unsubscribed themselves? Is it even possible? The reason I'm asking is because you can't delete someone who has unsubscribed themselves. If you try, their data will be scrubbed but the email address will stay in your list. Furthermore, if you try to subscribe someone who has unsubscribed by clicking on an unsubscribe link, you'll get "john#example.com is in a compliance state due to unsubscribe, bounce, or compliance review and cannot be subscribed." So in this situation we should check if they've unsubscribed themselves, and if so we can set their status to pending which will send the confirmation opt-in email. Otherwise, we can subscribe them via API without setting their status to pending and sending them an email and requiring them to click the link in the email.
As you've noted, if you try to delete someone in a compliance state, the API will reject your request but unfortunately doesn't return any useful response indicating as such. On the other hand, if you try to subscribe someone in a compliance state you should get a response in json form with status of 400 and a corresponding message. In my case it looks something like this:
{
"type":"http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/",
"title":"Member In Compliance State",
"status":400,
"detail":"johndoe#example.com is in a compliance state due to unsubscribe, bounce, or compliance review and cannot be subscribed.",
"instance":"1234567890abcdefg"
}
If you simply parse that response you can check for the value of status which is probably more reliable and forward compatible than the textual descriptors - and if applicable you can set member state to pending from there.
From Mailchimp support:
When a user is unsubscribed you'll see the parameter unsubscribe_reason and if it's an admin unsubscribe or an unsubscribe done via the API it will say "N/A (Unsubscribed by an admin)". However if it is done by the user it will often say "Unspecified" if they did not leave a reason or it may display a reason the user noted for unsubscribing. You can read more about the unsubscribe_reason parameter at the link below.
http://developer.mailchimp.com/documentation/mailchimp/reference/lists/members/
To expand on the answer from #nmit026, do a get-member-info api request and check for:
unsubscribe_reason == 'N/A (Unsubscribed by admin)'
In my opinion, this feels a bit hacky as the logic relies on comparison to a fairly specific string, but nonetheless, it is probably only correct approach at the moment.
We're moving from Mandrill to SparkPost. We figured that SparkPost's transmission is the closest thing to Mandrill's send-template message call.
Mandrill responded to those calls with a list of ids and statuses for each email. On the other hand SparkPost returns a single id and summary statistics (number of emails that were sent and number of emails that failed). Is there some way to get those ids and statuses out of the transmission response or at all?
you can get the message IDs for messages sent using the tranmissions API two ways:
Query the message events API, which allows you to filter by recipients, template IDs, campaign IDs, and other values
Use webhooks - messages are sent to your endpoint in batches, and each object in the batch contains the message ID
Which method you choose really depends on your use case. It's essentially poll (message events) vs. push (webhooks). There is no way to get the IDs when you send the transmission because they are sent asynchronously.
Querying message events API, while a viable option, would needlessly complicate our simple solution. On the other hand we very much want to use Webhooks, but not knowing which message they relate to would be troublesome...
The missing link was putting our own id in rcpt_meta. Most of the webhooks we care about do contain rcpt_meta, so we can substitute message_id with that.
I'm stacked too in this problem..
using rcpt_meta solution would be perfect if substitution would work on rcpt_meta but it's not the case.
So, in case of sending a campaign, I cannot specify all recipients inline but have to make a single API call for every message, wich is bad for - say - 10/100k recipients!
But now, all transmission_id are unique for every SINGLE recipient, so I have the missing key and rcpt_meta is not needed anymore.
so the key to be used when receiving a webhook is composed:
transmission_id **AND** rcpt_to
Is there a RESTful way to determine whether a POST (or any other non-idempotent verb) will succeed? This would seem to be useful in cases where you essentially need to do multiple idempotent requests against different services, any of which might fail. It would be nice if these requests could be done in a "transaction" (i.e. with support for rollback), but since this is impossible, an alternative is to check whether each of the requests will succeed before actually performing them.
For example suppose I'm building an ecommerce system that allows people to buy t-shirts with custom text printed on them, and this system requires integrating with two different services: a t-shirt printing service, and a payment service. Each of these has a RESTful API, and either might fail. (e.g. the printing company might refuse to print certain words on a t-shirt, say, and the bank might complain if the credit card has expired.) Is there any way to speculatively perform these two requests, so my system will only proceed with them if both requests appear valid?
If not, can this problem be solved in a different way? Creating a resource via a POST with status = pending, and changing this to status = complete if all requests succeed? (DELETE is more tricky...)
HTTP defines the 202 status code for exactly your scenario:
202 Accepted
The request has been accepted for processing, but the processing has not been completed. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place. There is no facility for re-sending a status code from an asynchronous operation such as this.
The 202 response is intentionally non-committal. Its purpose is to allow a server to accept a request for some other process (perhaps a batch-oriented process that is only run once per day) without requiring that the user agent's connection to the server persist until the process is completed. The entity returned with this response SHOULD include an indication of the request's current status and either a pointer to a status monitor or some estimate of when the user can expect the request to be fulfilled.
Source: HTTP 1.1 Status Code Definition
This is similar to 201 Created, except that you are indicating that the request has not been completed and the entity has not yet been created. Your response would contain a URL to the resource representing the "order request", so clients can check the status of the order through this URL.
To answer your question more directly: There is no way to "test" whether a request will succeed before you make it, because you're asking for clairvoyance.
It's not possible to foresee the range of technical problems that could occur when you attempt to make a request in the future. The network may be unavailable, the server may not be able to access its database or external systems it depends on for functioning, there may be a power-cut and the server is offline, a stray neutrino could wander into your memory and bump a 0 to a 1 causing a catastrophic kernel fault.
In order to consume a remote service you need to account for possible failures of any request in isolation of any other processes.
For your specific problem, if the services have no transactional safety, you can't bake any in there and you have to deal with this in a more real-world way. A few options off the top of my head:
Get the T-Shirt company to give you a "test" mechanism, so you can see whether they'll process any given order without actually placing it. It could be that placing an order with them is a two-phase operation, where you construct the order in the first phase (at which time they validate its creation) and then you subsequently ask the order to be processed (after you have taken payment successfully).
Take the credit-card payment first and move your order into a "paid" state. Then attempt to fulfil the order with the T-Shirt service as an asynchronous process. If fulfilment fails and you can identify that the customer tried to get something printed the company is not prepared to produce, you will have to contact them to change their order or produce a refund.
Most organizations will adopt the second approach, due to its technical simplicity and reduced risk to the business. It also has the benefit of being able to cope with the T-Shirt service not being available; the asynchronous process simply waits until the service is available and completes the order at that time.
Exactly. That can be done as you suggest in your last sentence. The idea would be to decopule resource creation (that will always work unless network failures) that represents an "ongoing request" of the "order acceptation", that can be later decided. As POST returns a "Location" header, you can then retrieve in any moment the "status" of your request.
At some point it may become either accepted or rejected. This may be intantaneous or it may take some time, so you have to design your service with these restrictions (i.e. allowing the client to check if his/her order is accepted, or running some kind of hourly/daily service that collect accepted requests).