Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Submit Deeply Nested Resource using Restful APIs (HATEOAS)

Say I have an application resource that contains contact details resources, and contact details contains addresses resources.

Eg.

Application
--> Name
--> Application Amount
--> Application Contacts 
--> --> Contact 1
--> --> --> Address
--> --> Contact 2
--> --> --> Address

When doing a POST to Application, I am creating the root application. For all sub resources like Application Contacts, I do a POST to create Contact 1 etc...

My question is, Application = to submit somewhere for processing, but I do not want to submit it before everything is filled in, aka all children resources.

So the order of submission
1) Create Application Resource --> POST /Application --> Get ID
2) Create Contact 1 Resource --> POST /Application/id/Contacts --> Get ID
3) Create Contact 1 Address Resource --> POST /Application/id/Contacts/id/Addresses
4) Create Contact 2 Resource --> POST /Application/id/Contacts --> Get ID 
5) Create Contact 2 Address Resource --> POST /Application/id/Contacts/id/Addresses
6) DECIDE TO SUBMIT HERE <--- ?? HOW?

Josh

like image 502
Joshscorp Avatar asked Nov 02 '22 18:11

Joshscorp


1 Answers

Your design isn't RESTful. Your resources are probably 1-to-1 mappings with your business entities? I don't advise this, because it exposes the guts of your domain model to the outside world, which can cause versioning problems. It also makes problems like this harder than they need to be - although you might be using a REST framework that forces this design on you :-( .

The thing to remember is that resources in REST are abstract representations of the element of your domain model that you want the outside world to see, and they may well need mapping and transformation before they can be converted to domain objects. They can be arbitrarily complex.

The solution here, I'd say, is to let the POST to create the Application also create the Contacts and their Addresses. The client can then either supply URLs for existing Contacts and Addresses (which the server can dereference to the domain objects), or the necessary details to create new ones in a single POST. Then the responsibility of creating and associating the entities in a transactional way falls upon the server. It just returns a reference to the URL that identifies the new Application. If you need to know the URLs for the Contacts, then you re-GET the Application, and it will contain them.

Assuming a JSON mime type for your resource, the initial POST might look like this:

{
    Name: "Application name",
    Amount: "123.00",
    Contacts: [
        {
            Name: "Contact name",
            Address: {
                HouseNumber: "45",
                StreetName : "Sesame Street"
            }
        }
    ]
}
Return: {href:  “/Application/6789”}

A GET to /Application/6789 would then return something like:

{
    Name: "Application name",
    Amount: "123.00",
    Contacts: [
        { mimeType: "application/vnd.com.myStuff.contact+json", href: "/Contact/203" }
    ]
}
like image 138
Stephen J. Anderson Avatar answered Nov 08 '22 04:11

Stephen J. Anderson