Building out the rest of the API

Now that we have covered the basics of constructing a REST API it is time to build out the remaining parts of the API for our auction system.

In these notes I am going to walk you through a design process that I use to identify what actions I will need for my auction API. This design process procedes by constructing a series of user stories that model interactions that users will need to have with the system. Each user story will consist of a set of goals, which are tasks that a user will want to complete. In the service of each of these goals I will set up HTTP URL, verb pairs and describe the structure of the objects that we will be passing back and forth to the server.

We have already implemented one user story in the two previous lectures, the user story centered around creating a new user account and then subsequently logging in to that account. These notes will walk you through the rest of the user stories our system will need to support.

Setting up a profile

After a user has established an account, we will offer them the opportunity to construct a profile with more information about themself.

Here is a set of member variables for a Java class showing the information that goes into a profile:

public class Profile {
  private String user;
  private String fullname;
  private String email;
  private String phone;
  private Shipping shipping;
  private String bio;
  private boolean ispublic;
}

If a user chooses to provide address information as part of their profile, that information will be embedded in the Profile as a Shipping object. That same object type gets reused later in the system whenever a customer wins an auction and wants to have the item shipped to an address that differs from their profile address. Here is the structure of the Shipping class:

public class Shipping {
  private int shippingid;
  private String user;
  private String displayname;
  private String addressone;
  private String addresstwo;
  private String city;
  private String state;
  private String zip;
}

To store profile information on the server, a user will start by POSTing a Profile object to the URL

/users/{id}/profile

where {id} is their user id. Likewise, a user can view their profile by doing a GET with the same URL. If users choose to update their profile information, they can do a PUT with that same URL.

Creating an Auction

When a seller wants to create an auction, they will start by POSTing an Auction object to the URL

/auctions

Here is the structure of that Auction object:

public class Auction {
  private String auctionid;
  private String seller;
  private String item;
  private String description;
  private String imageurl;
  private int reserve;
  private String opens;
  private String closes;
  private List<String> tags;
}

Since the auctionid will be generated automatically by the system, that field does not need to be present in the object that the user POSTS.

A seller can fetch a list of all of the auctions they have created by doing a GET with the URL

/users/{userid}/auctions

where {userid} is their user id.

Bidding on Auctions

To place a bid on an Auction users will want to start by viewing available auctions.

Doing a GET with the URL

/auctions

will fetch a list of all currently active auctions, that is auctions where the opens value is less than or equal to today's date and the closes value is greater than or equal to today's date.

To search for auctions that have a particular tag attached to them, users can do a GET with the URL

/auctions?tag=<tag>

To place a bid on an Auction a user will POST a Bid object to the URL

/auctions/{auctionid}/bids

where {auctionid} is the id of the auction they want to bid on.

Here is the structure of the Bid class:

public class Bid {
  int bidid;
  private String auction;
  private String bidder;
  private int bid;
  private String entered;
}

Since the bidid will be generated automatically by the system, that field does not need to appear in the POSTed object. Here bidder is the user id of the user placing the bid.

To view a list of all of the current bids for a particular auction, users can do a GET with the URL

/auctions/{auctionid}/bids

Winning auctions and shipping product

Once an auction concludes we will want to work through the purchasing and shipping process. As I explained in the first lecture, this is a complex, multi-step process.

Once a user has won an auction they will want to know that they have won. To fetch this information they can do a GET with the URL

/users/{userid}/offers

This will fetch a list of offers to purchase. A Offer object takes the form

public class Offer {
  String purchaseid;
  String auctionid;
  int bidid;
  int amount;
}

Here auctionid is the id of the Auction they won and amount is how much they bid. If they want to review the details of the auction they can pull up the full auction details by doing a GET with the URL

/auctions/{auctionid}

To accept this offer the user will POST an OfferResponse object to the URL

/purchases/offerresponse

An OfferResponse takes the form

public class OfferResponse {
  String purchaseid;
  String userid;
  boolean accept;
  int shippingid;
}

If the buyer wants to reject the offer they will simply set the accept field to false. This will cause their winning bid to be removed from the system, giving a new user the opportunity to purchase item.

If the buyer has accepted the offer they will be expected to provide a shipping address as part of the response. To view a list of all of the shipping addresses they have already entered into the system, the user can do a GET with the URL

/users/{userid}/shipping

where {userid} is their user id.

To create a new Shipping entry the user can POST a new Shipping object to the same URL.

Next, we will expect the auction's seller to provide a shipping estimate for this accepted offer.

To fetch a list of accepted offers sellers do a GET using the URL

/users/{userid}/accepted

This returns a list of Sale objects. A Sale object takes the form

public class Sale {
  String purchaseid;
  String auctionid;
  int bidid;
  Shipping shipping;
}

Here bidid is the id of the winning bid. To enter the shipping charge estimate the seller will POST a ShippingCharge object to the URL

/purchases/billshipping

A ShippingCharge object takes the form

public class ShippingCharge {
  String purchaseid;
  int charge;
}

where charge is the proposed shipping charge.

The buyer can see a list of all of their billed sales by doing a GET with the URL

/users/{userid}/billed

This will return a list of Bill objects, which take the form

public class Bill {
  String purchaseid;
  String auctionid;
  int bidid;
  int amount;
  int shippingcharge;
  Shipping shipping;
  String tracking;
}

To pay a bill the user will POST a BillResponse object to the URL

/purchases/billresponse

A BillResponse object takes the form

public class BillResponse {
  String purchaseid;
  String userid;
  boolean accepted;
}

To see a list of sales that have been fully paid, sellers will do a GET with the URL

/users/{userid}/sold

This will return a list of Bill objects for all of their confirmed sales. Sellers are expected to provide shipping confirmation for all sold items. To provide this confirmation they will POST a ShippingConfirmation object to the URL

/purchases/confirmshipping

A ShippingConfirmation object takes the form

public class ShippingConfirmation {
  String purchaseid;
  String tracking;
}

Once tracking numbers have been entered into the system buyers can view them by once again doing a GET with the URL

/users/{userid}/shipped

This will return a list of Bill objects, which will now contain tracking numbers for any billed, paid, and shipped items.