Skip to content

Instantly share code, notes, and snippets.

@hjr3
Created April 3, 2012 05:35
Show Gist options
  • Star 90 You must be signed in to star a gist
  • Fork 30 You must be signed in to fork a gist
  • Save hjr3/2289546 to your computer and use it in GitHub Desktop.
Save hjr3/2289546 to your computer and use it in GitHub Desktop.
Examples of RESTful API calls for E-commerce platforms

Examples of RESTful API calls for E-commerce platforms

These examples are type 3 RESTful API requests and responses. The JSON-HAL specification is used to implement HATEOAS.

Some of the examples are based on my work as architect of the RESTful API at http://www.hautelook.com. All proprietary information has been removed.

Relevant links

Examples

Add Item to Cart

A POST request to /member/109087/cart will create a cart resource for the member (if one did not exist) and add the inventory item to the cart. The Location header links to the cart resource that was created or updated. It is optional to add the JSON-HAL representation of that resource as the POST response, but not required.

POST /member/109087/cart HTTP/1.1
Host: api.example.com
Authorization: Basic username:password
Content-type: application/json
Accept: application/hal+json

{
    "inventory_id": 12345,
    "quantity": 1
}

HTTP/1.1 201 Created
Date: Mon, 20 Jun 2011 21:15:00 GMT
Content-Type: application/hal+json
Location: /member/109087/cart/14418796

Get Cart Contents

A GET request to /member/109087/cart will respond with the cart resource and list the contents of the cart items as embedded resources. A link is provided to the payment calculation URI.

GET /member/109087/cart HTTP/1.1
Host: api.example.com
Authorization: Basic username:password
Content-type: application/json
Accept: application/hal+json

HTTP/1.1 200 OK
Date: Mon, 20 Jun 2011 21:15:00 GMT
Content-Type: application/hal+json
Etag: 372b753d68c06990ea22b04b9c9fd4f8

{
   "_links":{
      "self":{
         "href":"/member/109087/cart"
      },
      "http://example.com/rels/payment":{
         "href":"/payment"
      }
   },
   "_embedded":{
      "http://example.com/rels/cart-item":[
         {
            "_links":{
               "self":{
                  "href":"/member/109087/cart/14418796"
               }
            },
            "id":"14418796",
            "quantity":1,
            "expire_time":"2009-09-11T08:00:00-07:00",
            "_embedded":{
               "http://example.com/rels/sku":[
                  {
                     "_links":{
                        "self":{
                           "href":"/skus/654654"
                        },
                        "http://example.com/images/cart/item":"http://example.com/product/6895/thumbnail.jpg"
                     },
                     "color":"Black",
                     "size":"S",
                     "returnable":false,
                     "price":49
                  }
               ]
            }
         }
      ]
   }
}

Calculate Payment

A GET request to /payment will calculate the total amount owed by the member based on the contents in the members cart. The calculation results, along with any discounts (coupons, giftcards, etc) are sent back for the member to review. The relation to http://example.com/payment/coupon allows the member to add and remove any coupons from the calculation.

The choice of shipping and billing addresses to be used during payment are sent back as well. The relations http://example.com/rels/billing and http://example.com/rels/shipping provide allow the member to add, remove and retrieve their billing and shipping addresses. The relations http://example.com/rels/payment/billing and http://example.com/rels/payment/shipping allow the member to apply a different shipping or billing address to the payment calculation.

GET /payment HTTP/1.1
Host: api.example.com
Authorization: Basic username:password
Content-type: application/json
Accept: application/hal+json

HTTP/1.1 200 OK
Date: Mon, 20 Jun 2011 21:15:00 GMT
Content-Type: application/hal+json
Cache-Control: private, no-store

{
   "_links":{
      "self":{
         "href":"/payment"
      },
      "http://example.com/rels/billing":{
         "href":"/member/109087/billing"
      },
      "http://example.com/rels/shipping":{
         "href":"/member/109087/shipping"
      },
      "http://example.com/rels/payment/coupon":{
         "href":"/payment/coupon"
      },
      "http://example.com/rels/payment/billing":{
         "href":"/payment/billing"
      },
      "http://example.com/rels/payment/shipping":{
         "href":"/payment/shipping"
      },
      "subtotal":49,
      "tax":0,
      "freight":5,
      "total":44,
      "_embedded":{
         "http://www.example.com/rels/coupon":[
            {
               "type":"dollarOff",
               "amount":"10",
               "code":"A0318A97"
            }
         ],
         "http://example.com/rels/shipping":{
            "_links":{ 
               "self":{
                  "href":"/shipping/135451" 
               } 
            },
            "first_name":"Heman",
            "last_name":"Radtke",
            "address":"1234 Day St.",
            "city":"Los Angeles",
            "state":"CA",
            "zipcode":"90015",
            "country_iso":"US"
         },
         "http://example.com/rels/billing":{
            "_links":{ 
               "self":{
                  "href": "/billing/135451" 
               } 
            },
            "first_name":"Herman",
            "last_name":"Radtke",
            "address":"1234 Day St.",
            "city":"Los Angeles",
            "state":"CA",
            "zipcode":"90015",
            "country_iso":"US",
            "card_number":"1111",
            "card_type":"mastercard",
            "card_exp_year":"2015",
            "card_exp_month":"01"
         }
      }
   }
}

Place Order

A POST request to /orders will create an order resource based on the contents of the members cart.

POST /orders HTTP/1.1
Host: api.example.com
Authorization: Basic username:password
Content-type: application/json
Accept: application/hal+json

HTTP/1.1 201 Created
Date: Mon, 20 Jun 2011 21:15:00 GMT
Content-Type: application/hal+json
Location: /orders/453435
@andreineculau
Copy link

I suggest you read: http://blog.programmableweb.com/2011/11/18/rest-api-design-putting-the-type-in-content-type/

Have you considered JSON hyper schema? If so, what made you go with HAL?

@hjr3
Copy link
Author

hjr3 commented Apr 22, 2012

Interesting article. I chose HAL because it provides a simple standard for hypermedia in JSON. If I was using XML I would have used the atom standard. I also strongly considered Collection+JSON.

I am wary about using schema's for RESTful API's. The web is built on the idea of being liberal with what you accept and strict with what you send.

@mikeschinkel
Copy link

Hi @hjr3,

This is one of the better examples I've seen for leveraging a hypermedia representation, kudos.

A couple things I'd like to ask about it if you don't mind 10 months later. I'd like to better understand how you are using the link relations in the position of object property name.

Thanks in advance.

@jmonteiro
Copy link

Hello @hjr3,

Just like @mikeschinkel, I'm also curious about how you think it's best to handle metadata on "http://example.com/rels/{type}".

Thanks!

@timbunce
Copy link

Hi @hjr3. Thanks for this. It would be helpful to me, and others I'm sure, if you could add some notes about how you format error responses.

@lsmith77
Copy link

why isn't the payment calculation and order done on a specific cart resource?

@kiran8g
Copy link

kiran8g commented Jan 8, 2015

Please provide samples code for java client to consume application/hal+json

@oliveiraddb
Copy link

Hi all, great gist! Restful APIs get me confused sometimes :S

I have some questions: What if I want to expose an method to get the last 5 new items added, how can i do that?

annicetest.com/api/products?limit=5&new and handle that new attribute on server?

or should I expose an orderBy attribute too and do something like that: annicetest.com/api/products?limit=5&order=created[desc] ?

Can anyone help me understand that?

@Davidmichael4u
Copy link

Davidmichael4u commented Aug 2, 2016

Intro : [https://gist.github.com/deepak-rajpal/66e9f1abec8be2857074]

REST API can be deployed for functions like browsing through the app, adding to cart, chat, login etc while SOAP can be used for those which involve top-of-the-line security like payment transactions (payment gateway) etc.

Major Diff : [http://stackoverflow.com/questions/19884295/soap-vs-rest-differences]

Major sites uses:
Content management systems like Joomla, WordPress, social media like Twitter, LinkedIn make use of REST while cloud-based CRM like Salesforce and payment gateways like PayPal are built using SOAP.

REST uses a single line of code.
The module (phonebook), action (User Detail) and ID (12345) are directly called locally whereas the same process is split into multiple client server interactions in case of SOAP

<?xml version=”1.0″?><soap:Envelope xmlns:soap=”http://www.w3.org/2001/12/soap-envelope&#8221;

SOAP
<soap:body pb=”http://www.acme.com/phonebook”&gt; <pb:GetUserDetails> <pb:UserID>12345</pb:UserID> </pb:GetUserDetails> </soap:Body> </soap:Envelope>

For more visit : http://blog.contus.com/rest-api-vs-soap-api-for-mobile-ecommerce-app/

@hjr3
Copy link
Author

hjr3 commented Jan 6, 2022

For some reason I stopped receiving notifications on this for a long time.

When it comes to link relations, the format does not matter. I treat the link relations as a URI. I am not extracting type from the link relation. If the link relation seems too verbose, you can shorten it with curies as shown on https://stateless.group/hal_specification.html. For example: "curies": [{ "name": "ea", "href": "http://example.com/docs/rels/{rel}", "templated": true }],

@mikeschinkel The link relation should link to human readable documentation for that resource. Machines (clients) should treat the link relation (curie form or URI form) as an opaque identifier. Humans should write code so that the machine understands how to handle each link relation. You are right that this violates Roy's idea of hypertext. HAL is a pragmatic attempt to make JSON responses more hypermedia-like. It does not go full hypermedia like Siren or Collection+JSON. I like the pragmatic aspect of HAL because most client developers will not spend the time to properly use a Siren or Collection+JSON response.

I believe that graphql has a much better client developer story (especially around tooling). I wish we would have built such a thing for hypermedia.

@timbunce I follow https://github.com/blongden/vnd.error for error responses

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment