Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for HAL-FORMS #66

Open
carlobeltrame opened this issue Mar 3, 2021 · 0 comments
Open

Add support for HAL-FORMS #66

carlobeltrame opened this issue Mar 3, 2021 · 0 comments

Comments

@carlobeltrame
Copy link
Member

carlobeltrame commented Mar 3, 2021

HAL is fundamentally a read-only technology. So far, we have allowed the users to perform their own custom write operations by specifying the HTTP method to use and constructing a payload in the right format manually ($post(...), $patch(...), ...). In ecamp3, the payload format, required fields, etc. are not documented at all for users of the API.

There have been some efforts to push the standard further, in order to allow the API to specify more accurately and in a standardized way, how the user can interact with it. The most prominent such evolution of HAL I found is HAL-FORMS. HAL-FORMS goes even further by specifying the crucial form elements in a user interface, with the ultimate goal that the frontend (or API client) of an application should not have to be redeployed when the API changes some fields. HAL-FORMS is adopted by Spring HATEOAS, although being marked as an unstable specification for the time being.

This sounds intriguing, but obviously comes with its own set of problems, at least in the realm of designing and customizing the look of the forms. But we could start by supporting _templates as specified in HAL-FORMS in a similar way to how we support $post etc.:
API response in HAL-FORMS format:

{
  id: 345,
  firstName: 'John',
  lastName: 'Doe',
  _links: {
    self: {
      href: '/api/users/345',
    },
  },
  _templates: {
    "edit" : {
      "title" : "Edit user",
      "target": "/api/users/345",
      "method" : "PATCH",
      "contentType" : "application/json",
      "properties" : [
        {"name" : "firstName", "required" : true, "value" : "John", "prompt" : "First name"},
        {"name" : "lastName", "required" : false, "value" : "Doe", "prompt" : "Last name"},
      ],
    },
  },
}

Frontend code that uses this data:

const user = this.api.get().users({ id: 345 })

// Proposal: Reference templates with a $ sign and the template key

// The next line will create a PATCH request to /api/users/345,
// with the payload { firstName: 'Jonathan' }
await user.$edit({ firstName: 'Jonathan' })

// The next line will create a PATCH request to /api/users/345,
// with the payload { firstName: 'Jonathan', lastName: 'Doe-Smith' }
// (because firstName is required)
user.$edit({ lastName: 'Doe-Smith' })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant