hoodiehq / account-json-api Goto Github PK
View Code? Open in Web Editor NEWREST-API Blueprint for all things user accounts and sesions
Home Page: http://docs.accountjsonapi.apiary.io
License: Apache License 2.0
REST-API Blueprint for all things user accounts and sesions
Home Page: http://docs.accountjsonapi.apiary.io
License: Apache License 2.0
Hey folks, I have a lot of questions about the API URLs and returned status codes, also, it seems to me that a lot of possible error responses are omitted from the API, so here is a compilations of questions and feedback about the current defined API for further discussion.
Disclaimer: I am focusing first on the "User" (i.e. non admin) part of the API, so this discussion is only about that part.
PUT /session
Possible responses:
201
401
type
provided in the request (data.type
): 409
*GET /session
Possible responses:
200
401
401
/404
?**DELETE /session
Possible responses:
204
401
401
/404
?**PUT /session/account
About the URL:
POST /accounts
(this is the URL for admins)PUT /session/account
when the session does not exist (since, if the session exist, then we already have an account for it, haven't we?)Possible responses:
201
type
provided in the request (data.type
): 409
*GET /session/account
Possible responses:
200
401
401
/404
?**PATCH /session/account
Possible responses:
204
401
401
/404
?**409
(this might not be relevant for us)type
and id
provided in the request don't match (data.type
): 409
***DELETE /session/account
Possible responses:
204
401
401
/404
?**GET /session/account/profile
Possible responses:
200
200
with null
as primary data. See JSON API spec.401
401
/404
?**PUT /session/account/profile
Possible responses:
201
401
401
/404
?**type
provided in the request (data.type
): 409
*PATCH /session/account/profile
Possible responses:
204
401
401
/404
?**409
(this might not be relevant for us)type
and id
provided in the request don't match (data.type
): 409
****This is mentioned in the JSON API spec referring to creating users with POST
, I guess it also applies to PUT
?
**Some considerations about this one:
401
?404
can be interpreted as: URL doesn't exist, but if the URL doesn't exist, we can't really use PUT
for the creation of the resource, can we?*** See here.
@gr2m, @tthew, @karlwestin comments?
Follow up for #14
As an admin, I would like to be able to create a user session, so I can debug an account without messing with passwords.
I would suggest the route POST /account/{id}/sessions
for that. Without any body (does JSON API allow that?).
The response would look like this:
{
"links": {
"self": "https://example.com/accounts/abc1234/sessions/sessionid123"
},
"data": {
"id": "sessionid123",
"type": "session",
"relationships": {
"account": {
"links": {
"related": "https://example.com/accounts/abc1234"
},
"data": {
"id": "abc1234",
"type": "account"
}
}
}
}
}
This implies that we would also need a GET /accounts/{id}/sessions/{id}
and a DELETE /accounts/{id}/sessions/{id}
route, which works for me.
Any objections / thoughts?
current state is at
http://docs.accountjsonapi.apiary.io/#reference/requests/request-collection/create
source is here:
https://github.com/hoodiehq/account-json-api/blob/master/apiary.apib#L725
links.self
is optional. If no resource is persisted in the database, it won't be set (not relevant anymore, see comment below)We need support a client-generated ID for for Hoodie. JSON API explicitly supports client-generated resource IDs, so let’s put it into the spec, that it’s allowed, but not required of course
To keep the summary on the README inline with the the API docs we should change the the admin route parameters to use id
instead of username
Now that I'm implementing the account-json-api
spec, I find the /session/account
route confusing, because an account can exist and be accessible even without a session. For example, a user can signed up for an account but not sign in until the account is confirmed.
For that reason, I'd suggest to rename /session/account
to /account
, and /session/account/profile
to /account/profile
We now suggest to get rid of /session/account
altogether, and use /accounts/{id}
instead
According to this:
http://restcookbook.com/HTTP%20Methods/patch/
"Also, the PUT method is idempotent. PUTting the same data multiple times to the same resource, should not result in different resources, while POSTing to the same resource can result in the creation of multiple resources."
Since the response of this request would have the Created resource (the session), which includes a sessionId. and I think multiple requests would end up with different sessionIds. So using PUT is wrong, and it should be a POST.
I liked the idea of using usernames as IDs in the URLs, but it’s inconsistent with all the rest of our APIs, and could potentially cause issue with JSON API clients.
For example GET /accounts/jane-doe
would return
{
"links": {
"self": "https://example.com/accounts/jane-doe"
},
"data": {
"id": "def678",
"type": "account",
"attributes": {
"username": "jane-doe",
}
},
"relationships": {
"profile": {
"links": {
"related": "https://example.com/accounts/jane-doe/profile"
},
"data": {
"id": "def678-profile",
"type": "accountProfile"
}
}
}
}
But data.id
is "def678"
, not "jane-doe"
. I'm not sure if this is JSON API compliant or not, but when in doubt, I'd rather avoid confusion.
Not using the username in the URLs also prevents issues with weird characters in usernames.
I think we can remove the PATCH /session/account
route entirely, and make all account properties after sign up read only, without exception. The security requirements / workflows to change a username or a password are app-specific, so I'd suggest that we use the requests
API for that. I think it's perfectly suited for that.
In Hoodie’s implementation, the handlers for the different requests can be defined with requests
option passed to the hapi plugin. For example the following request handler would require a x-password
header to be sent, and the PUT
request against CouchDB would happen with basic auth, using the username and password, and will therefore fail if the password is incorrect. The user's session is ignored entirely.
var options = {
/// ...
requests: {
updateAccount: function (request, reply) {
var server = request.connection.server
var user = request.auth.credentials
var password = request.headers['x-password']
var promise = server.plugins.account.api.accounts.update(user.id, {
username: request.payload.username,
password: request.payload.password
}, {
auth: {
username: user.username,
password: password
}
})
reply(promise)
}
}
}
That would also make the separation of accounts & profiles more clear.
Any thoughts @patriciagarcia @tthew?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.