How do I describe POST links in HAL?
I'm designing a RESTful API with HATEOAS constraints, similar to Wikipedia's HATEOAS example but expressed in HAL JSON (dropping the scheme, host, etc. for clarity):
GET /accounts/12345
{
"id" : 12345,
"balance" : 100.00
"_links" : {
"self" : {
"href" : "/accounts/12345"
},
"transfer" : {
"href" : "/accounts/12345/transfer{?amount,target}",
"templated" : true
}
}
}
To perform the "transfer" action, the client would presumably do:
GET /accounts/12345/transfer?amount=100.00,target=54321
{
"id" : 34567,
"amount" : 100.00
"_links" : {
"self" : {
"href" : "/transfers/34567"
},
"source" : {
"href" : "/account/12345"
},
"target" : {
"href" : "/account/54321"
}
}
}
Invoking the "transfer" link via GET creates a new ressource in "transfers". But doing a GET to create a new resource is not idempotent and it "feels" wrong; a RESTful resource centric API would POST:
POST {amount: 10.00, source: 12345, target: 54321} /transfers/
{
"id" : 34567,
"amount" : 100.00
"_links" : {
"self" : {
"href" : "/transfers/34567"
},
"source" : {
"href" : "/account/12345"
},
"target" : {
"href" : "/account/54321"
}
}
}
But how do I describe this POST and the required form elements in HAL so the client can just do the "Right Thing" without being hard-coded? Perhaps something like:
{
"id" : 12345,
"balance" : 100.00
"_links" : {
"self" : {
"href" : "/accounts/12345"
},
"transfer" : {
"href" : "/transfers{?amount,source,target}",
"templated" : true,
"method" : "POST"
}
}
}
But method
not part of the HAL specification and there's no analogous identifier -- so it feels like I'm on the wrong track...
Perhaps my client should just "know" that a GET of transfer
returns matching transfer resources, and a POST to transfer
creates a new transfer resource.
FWIW, my implementation uses Spring Boot 2 with Spring HATEOAS so the follow-up question is how to express this with Spring HATEOAS...