Creating a simple / pseudo API on rails 3? - ruby-on-rails

I'm trying to create something which does the following:
if I have a products table that lists all products.
then I have a "purchase" table, which contains all transactions for people buying products.
lets say the products are like groupons (digital products) - they have to be set to "used" once they're used, either by the person who bought them, or the person who sold them.
person X buys a product, with key "XYZABC123"
the product is from company Micromartsystems
Micromartsystems has the api key "DFJSDda3290dssdj1"
if someone redeems their product on Micromartsystems, and uses the redemption key "XYZABC123", The admin of Micromartsystems see that in their backend.
Then lets say say they visit a link like mysite.com/redeem?api_key=DFJSDda3290dssdj1&redemption_key=XYZABC123
Because only Micromartsystems knows their API key, and only they should see a product with the key XYZABC123 (as each key will be unique for each purchase) - they can make links in their backend which automatically mark products as used on mysite.com.
From my side of things, it'll be pretty easy to grab those params and mark a transaction as redeemed if the URL has been accessed.
Does this make sense as a good way to do this?
I've never built an api, or something that links up with external apps, so I'm kind of just guessing here.

That will work. Personally, I will design the api restfully instead of using url params. something like this:
http://yousite.com/account/DFJSDda3290dssdj1/redeem/XYZABC123

Related

How to know if data POSTed by client app to an API are original/not altered

I am new to web development and I have a question which might sound dumb.
The question:
Let's say we have a microservices architecture, where the microservices live in the back end and in the front end there is a client app that collects data from the microservices by consuming their APIs and then builds some HTML, populates it with that data and serves it to the user.
How can I know that the data that the user POSTs back to my client app, and eventually to my microservices, isn't "altered" by the user in a way to exploit our business model? By the term "altered" it doesn't mean necessary malicious data to harm our system, like an SQL injection input, or invalid data, like unaccepted values, but valid data that are not in their original values, like a "mistake" happened.
Example:
Imagine we have an "e-commerce" website based on microservices, where there is a "Catalog" microservice, which holds all the products of our business along with their information (price, stock, etc) and a "Basket" microservice which holds the Basket for each user of our website. We also have an MVC client app that communicates with these microservices by internally consuming the APIs provided by them.
In the Catalog API there is a GetAllProducts endpoint, that GETs all the products of our Catalog to the caller. The client app calls that endpoint on Catalog API, gets the data, populates the HTML and serves it to the user.
In the Basket API there is an AddProductToBasket endpoit, that POSTs a ProductDTO object which the microservice will validate and then store to the user's Basket. The ProductDTO object contains information like ProductId, ProductName, UnitPrice, Units, etc.
A scenario like the one I tried to describe above is when the user, after GETing all the Catalog products through the client app, he creates an "altered" ProductDTO and POSTs it back to AddProductToBasket endpoint (again through the client app). The "altered" ProductDTO will look like this:
"ProductDTO":{
"ProductId":"1234",
"ProductName":"PlayStation 5",
"UnitPrice":5,
"Units":1
}
While it should have looked like this, based on the data the Catalog API returned:
"ProductDTO":{
"ProductId":"1234",
"ProductName":"PlayStation 5",
"UnitPrice":500,
"Units":1
}
As you can see, the user is trying to exploit our business model by adding a product to his Basket with a lower price than the original. But the same alteration in POSTed data could happen with any of the ProductDTO properties.
My question is, how can I know, when I receive the ProductDTO at the Basket microserice, that the Price field has an incorrect value? Note that the Basket microservice doesn't store the information of the products, as this is out of the Basket's context. Products information are stored in Catalog microservice.
A probable solution:
A solution I can think of is to change the POSTed ProductDTOs to look like this:
"ProductDTO":{
"ProductId":"1234",
"Units":1
}
The idea is that now the ProductDTO object will instead be POSTed to the Catalog API endpoint (let's say to a RequestToAddProductToBasket endpoint) and the Catalog will only receive the ProductId and the desired Units from the user. It will then perform some business-rules level validation (e.g. there is available Stock for the desired Units) and then it will send to the Basket a new ProductDTO object, populated with all the necessary values, like ProductName, Price, Units, etc, though a back-end communication channel (like an Event Bus).
Basket, in turn, will receive the new ProductDTO and will use the data from it to add the Product to the user's Basket. This way it's "guaranteed" that the newly added Product has original data.
-
I just have a feeling that my way of thinking misses something obvious and I am over-complexing the solution. It's also probable that I have not understand how the client apps work and that it isn't that easy to POST an "altered" object to an API through the client app.
Please, let me know if the "problem" that I'm seeing here is real or not and if my proposed solution is a viable one or if there is a better workaround.
Thanks in advance.

Is it okay to allow orders to be placed in rails web app without session data or users class

I have a question for a project I am working on. I am working on a RoR project in which a site is selling a single type of item, a book. The person I am creating this for does not want to deal with users creating user account to check out as the sales season is very short for this product, the purchases are done once per year, and the site only sells a single item.
I am wondering if there is something wrong with the implementation I am thinking of. What I was envisioning was a single database class called Orders. visitors to the site would simple fill out an order form with payment details through stripe and click submit. If they payment clears, the order with all the Orders information would be persisted to the DB. If the payment fails then it is not persisted and the relevant error information is displayed in using flash.
I suppose the meat of my question is; is there anything inherently 'wrong' about implementing this model without a users class and just having visitors to the site place orders?
I am a fairly new developer and this is my first big project so any feedback is appreciated!
If your requirements say that it is okay, then it is okay, if your requirements say it is not okay, then it is not okay.
There's not more to say, since only you know what your requirements are.

Organizing and grouping sophisticated processes in rails

As an example, lets say I have 4 models: Product, Order, Customer, Store
When an order is placed by a customer in a store, the store's owner would get an email asking to confirm the UPC code on the product. Once confirmed, the customer would get an email with a code that when they enter it into their portal, it activates the product.
There is a lot of logic here, which spans several models. For example, when the order is completed, it creates a new inactive product with a confirmation key. The store owner accesses this product by its confirmation key and adds the upc information to it. Only then, once the product has upc information can the customer confirm it.
TL;DR - My question is, what is the best way to group a large process, which involves many models, into a central location? Instead of accessing several other models from within one model, it would make more sense to have it centralized. Is there a best-practice for this type of logic?
This case is typically going to result in a "Service Object" that would be placed in /lib.
This allows for testing the workflow in isolation and doesn't fatten up models unnecessarily.
You can find a good intro to Service Objects here:
https://blog.engineyard.com/2014/keeping-your-rails-controllers-dry-with-services
http://multithreaded.stitchfix.com/blog/2015/06/02/anatomy-of-service-objects-in-rails/

Amazon Product API - How to get items for sale by price?

I have a strage requirement from a client, he needs to display a ramdom selection (100 - 200 items from mixed categories) of products for sale on & shipped by Amazon but ordered by price. The idea is to allow people find gift ideas based a user input price point.
I have been looking through the API docs but cannot see an obvious way to find search by price, I am thinking of writing a script to "copy" large parts of the amazon product catalogue into a local database & have it update every few weeks, then use this for user searches, but this does not feel right / their must be a better way.
Has anyone any experience with this type of problem? Thanks!
You would want to use the Amazon Product Advertising API. Using this API you would want to perform a SearchIndex-ItemSearch query. Possible parameters to ItemSearch are available on the API Docs here
You can see in the docs that you cannot query by MinimumPrice and MaximumPrice on SearchIndex: All. However, if you search specific indexes, it allows you to do a price related search.
I would guess that you can agree with your client which categories should the items be from. Then you can just query them one by one.
Amazon's database changes very often. Hence, caching data for a week without updating may not be desirable.

what is the standard for creating a web REST API for adding new items

i have a order catalogue web site and i want to create a REST API so people can create their own apps and Add an Order or Update an existing order:
Lets say an order has:
OrderId
Product
Quantity
ShippingType
So i need some API to allow someone to send in a new order (orderid would be blank as that would be in the response).
How do you deal with passing in items like Product or Shipping type. These are tables in my db and are keyed off their own specific primary key id. Should the NewOrder API ask for a string name for these fields, should it ask for the id. If it asked for the ID, that would assume they would have to call the GiveMeProductList() method upfront (which gives you the name and id of all product as a dataset).
What is the standard for dealing with this?
Martin Fowler has a good post about the steps toward the glory of REST that you might find useful to come up with REST API.
The media type that I use for sending this information to the server can handle both scenarios, Id and Code/Name. If the user enters the product code manually then I send up the code, if the user asks to pick from a list then I provide the list and send back the Id.

Resources