Context :-
I'm validating my rest apis in spring boot. There's a transaction id that is being sent in every API call. I'm writing a custom annotation to ensure that the transaction id that is sent every time is unique. Here's an example of the request api body :-
{
"timestamp": "2020-05-12T04:15:28.318Z",
"txnid": "acscscs-4a18-11e8-96ff-05sdsadd",
"cust_id": "abc#gmail.com"
}
How do I ensure that the txnid transaction id is not repeated i.e. if I use the same transaction id twice then there should be an error thrown?
I was planning to save each transaction id to customer id map in a table, query the table to check if the transaction id is unique. Is this an efficient method?
Or is there any other efficient/simpler method to achieve the same?
You solution is fine, but the downside is database might not be the source of truth for txnid. Lets say txnid is present is saved in api but saving in database failed.
I would suggest the following solution:
Query the api for txnid on the fly (assumption: an api to provide the response HTTP.OK 200 if the txnid is present or else HTTP.NOT_FOUND 400). The api will be the only source of truth in this case.
Related
This is my scenario.
I've created an ASP.NET Web APi solution with numerous microservices to process orders from a shopping cart.When posting an order consisting of a Guid identifier of a shopping cart, and a customer name, instead of posting immediately to an EF Core database, I put the request into a RabbitMQ queue. This POST method is supposed to
return Created("", new { orderId = returnedOrder.OrderGUID })
that is, an object containing the orderGUID as it is in the database. Let me say first, that through this long chain of microservices, I have no problems reading into the database, the order ends up there as it should.
Another service, OrderProcessor, consumes the process from the (RabbitMQ)ueue, and sends it to the OrderManager, which is responsible for reading into the database through DbContext. The register method there is void, since I see no reason to return anything from it. It simply creates the Order object from a DTO model, and uses Context.Add and Context.SaveChanges to do it's job.
My problem is this.
The original POST method, which places the order in the queue, returns Accepted() to the HttpResponseMessage in the API Gateway, which is received in the HttpPost method. It seems to me, the Guid of the newly created order record in the database, is nowhere to be found in the received response message.
Even if I could put something as parameters into Accepted(), what would be the point? When the POST method is sending to the RabbitMQ queue, it has no idea what will be the order Guid when it is placing the request into the queue. The OrderGUID is the primary identity key of the Order record, created in the database.
Simply put, how can I, or can I even, get the order Guid into the latter POST method, the one which receives the request in the Postman request originally, or any request source, for that matter?
Solved by creating a new column in the order table, which can be set directly unlike an ID, which is created at database insert time. That new column could then be set directly in the DTO (data transfer object) models and read manually into the database record.
Which means I can return the new column Guid, as a response in the API Gateway controller's HttpPost method. Had to rebuild the database, but that still was quicker than having to scratch my head countless hours how to go about it the other way.
I don't know wheather anyone had this type of issue before or not! So but basically when i do save object it insert random order but not actual order in which i am sending it from POST api via UI. Below is my json object which i am sending to spring jpa for insertion,
{"expense":"wwww","amounts":[{"amount":"23","version":0},{"amount":"12","version":0},{"amount":"27","version":0},{"amount":"22","version":0},{"amount":"22","version":0},{"amount":"1111","version":0}],"version":0}
and this amounts are the Set<expense> amounts into my parent object as #manytomany relationship. And data insert into the random order but it should have insert the order which it sent from, correct me if i am wrong anywhere. In database it saves like 22,12,22,1111,,23,27 which is random.
In Java the Set interface doesn't guarantee any order. You can use a SortedSet for your mapping, or use a List. Both can be ordered and will preserve the one received from some JSON.
Some documentation :
Set Javadoc
SortedSet Javadoc
I have 2 types of transaction :
orderrequest ( provide details including orderer name and transaction id )
ordereraccept (provide id of the orderrequest transaction being accepted)
within the transaction processor function of orderaccept i want to refer to the previous orderrequest transaction using the id to perform validation
i was thinking of using some form of historian but have not been able to get anything to work .
In the test section of composer playground i am able to view previous transactions so I just need a way to do this within a transaction processor function
Thanks a lot
I want to save data of a form into two tables simultaneously. The form contains multiple identical rows with some fields like
item, unit, unit_price, total.
1.) In the table1 I would like to save some data like id(auto generated, primary key), date, creator.
2.) In table2 I would like to save the id(auto generated, primary key), fid(id of the table1, foreign key), item, unit, unit price, total. Remember, in table2 multiple rows will be save from the form data.
I can't figure it out. Please help me with a valid step by step example, and please don't use static or pre-defined data, take the data from form only.
Is your form an HTML form on a web page, and are you writing a Spring MVC application? Have you setup Spring Security, or some other authentication mechanism such that you know who the user is? If so, here is one approach:
Define a plain old Java object (POJO) with fields id, unit, unit-price, total, creator, currentDate; perhaps you would name it Item.
Define another plain old Java object perhaps named "ItemHistory", with its own ID and a reference to an Item.
In the first POJO ("Item") include a reference to a list of ItemHistorys.
Annotate both classes with Hibernate/JPA annotations, such that the Item has a OneToMany relationship to ItemHistory.
Define a Spring MVC controller with a method annotated as a POST method, with an Item as one parameter, and an Authentication as another parameter (supposing you have configured Spring Security, the Authentication will automatically be populated with the identity of the currently-logged-in user. In this method, set the currentDate and author of the Item to the current date and the principal from the Authentication parameter. If it is a new Item (no id yet), add the first ItemHistory as a copy of the Item itself. If it is an existing item, add another ItemHistory if needed.
Define a Spring bean, perhaps named ItemService, with a method annotated as transactional, that takes an Item and saves it. Call this bean from the REST controller. Such a Spring bean is known as a DAO (data access object).
There are other strategies, but if you already have Spring MVC, Spring Security, and Hibernate/JPA configured to your needs, this one is pretty straight-forward.
I implementing RESTful API service and i have a question about saving related records.
For example i have users table and related user_emails table. User emails should be unique.
On client side i have a form with user data fields and a number of user_email fields (user can add any number of fields independently). When the user saves the form i must first make query to create record in users table to get her ID, and only then i can make query to save user emails (because in now i have id of record which come with response after saving user data). But if user enters not unique email in any field then the request will fail. So I create a record in the users table but not create record in user_emails table.
What are the approaches to implement validation of all this data before saving?
This is nor related restful api but transactional processing on the backend. If you are using Java, with JPA you can persist both element in the same transaction then you can notice if there is a problem and rollback the entire transaction returning a response.
I would condense it down to a single request, if you could. Just for performance's sake, if nothing else. Use the user_email as your key, and have the request return some sort of status result: if the user_email is unique, it'll respond with a success message. Otherwise, it'd indicate failure.
It's much better to implement that check solely on the server side and not both with the ID value unless you need to. It'll offer better performance to do that, and it'll let you change your implementation later more easily.
As for the actual code you use, since I'm not one hundred percent on what you're actually asking, you could use a MERGE if you're using SQL Server. That'd make it a bit easier to import the user's email and let the database worry about duplicates.