Skip to content

Commit a593cbf

Browse files
committed
Move post slug endpoint & add endpoints for users
closes #3187 - move slug endpoint to post/slug/:slug - create similar slug and email endpoint for users - add/update tests
1 parent 09e03f4 commit a593cbf

File tree

7 files changed

+372
-236
lines changed

7 files changed

+372
-236
lines changed

core/server/api/index.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ init = function () {
4949
* @return {Promise(String)} Resolves to header string
5050
*/
5151
cacheInvalidationHeader = function (req, result) {
52-
var parsedUrl = req._parsedUrl.pathname.replace(/\/$/, '').split('/'),
52+
var parsedUrl = req._parsedUrl.pathname.replace(/^\/|\/$/g, '').split('/'),
5353
method = req.method,
54-
endpoint = parsedUrl[4],
55-
id = parsedUrl[5],
54+
endpoint = parsedUrl[0],
55+
id = parsedUrl[1],
5656
cacheInvalidate,
5757
jsonResult = result.toJSON ? result.toJSON() : result,
5858
post,
@@ -104,16 +104,15 @@ locationHeader = function (req, result) {
104104
location,
105105
post,
106106
notification,
107-
parsedUrl = req._parsedUrl.pathname.replace(/\/$/, '').split('/'),
108-
endpoint = parsedUrl[4];
107+
endpoint = req._parsedUrl.pathname;
109108

110109
if (req.method === 'POST') {
111110
if (result.hasOwnProperty('posts')) {
112111
post = result.posts[0];
113112
location = apiRoot + '/posts/' + post.id + '/?status=' + post.status;
114-
} else if (endpoint === 'notifications') {
113+
} else if (endpoint === '/notifications/') {
115114
notification = result.notifications;
116-
location = apiRoot + '/notifications/' + notification[0].id;
115+
location = apiRoot + endpoint + notification[0].id;
117116
}
118117
}
119118

core/server/api/users.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ users = {
5858
* @returns {Promise(User)} User
5959
*/
6060
read: function read(options) {
61-
var attrs = ['id'],
61+
var attrs = ['id', 'slug', 'email'],
6262
data = _.pick(options, attrs);
6363

6464
options = _.omit(options, attrs);
@@ -250,7 +250,7 @@ users = {
250250

251251
/**
252252
* ### Change Password
253-
* @param {password} object
253+
* @param {password} object
254254
* @param {{context}} options
255255
* @returns {Promise(password}} success message
256256
*/

core/server/middleware/index.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,6 @@ module.exports = function (server) {
288288

289289
// ### Caching
290290
expressServer.use(middleware.cacheControl('public'));
291-
expressServer.use(subdir + '/api/', middleware.cacheControl('private'));
292291
expressServer.use(subdir + '/ghost/', middleware.cacheControl('private'));
293292

294293

@@ -304,7 +303,7 @@ module.exports = function (server) {
304303

305304
// ### Routing
306305
// Set up API routes
307-
expressServer.use(subdir, routes.api(middleware));
306+
expressServer.use(subdir + routes.apiBaseUri, routes.api(middleware));
308307

309308
// Set up Admin routes
310309
expressServer.use(subdir, routes.admin(middleware));

core/server/routes/api.js

Lines changed: 57 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,71 @@
11
// # API routes
22
var express = require('express'),
33
api = require('../api'),
4-
apiRoutes;
4+
apiRoutes,
5+
resources;
6+
7+
resources = {
8+
posts: function (router) {
9+
router.get('/posts', api.http(api.posts.browse));
10+
router.post('/posts', api.http(api.posts.add));
11+
router.get('/posts/:id', api.http(api.posts.read));
12+
router.get('/posts/slug/:slug', api.http(api.posts.read));
13+
router.put('/posts/:id', api.http(api.posts.edit));
14+
router.del('/posts/:id', api.http(api.posts.destroy));
15+
}
16+
};
517

618
apiRoutes = function (middleware) {
719
var router = express.Router();
20+
// alias delete with del
21+
router.del = router.delete;
822

923
// ## Posts
10-
router.get('/ghost/api/v0.1/posts', api.http(api.posts.browse));
11-
router.post('/ghost/api/v0.1/posts', api.http(api.posts.add));
12-
router.get('/ghost/api/v0.1/posts/:id(\\d+)', api.http(api.posts.read));
13-
router.get('/ghost/api/v0.1/posts/:slug([a-z-]+)', api.http(api.posts.read));
14-
router.put('/ghost/api/v0.1/posts/:id', api.http(api.posts.edit));
15-
router['delete']('/ghost/api/v0.1/posts/:id', api.http(api.posts.destroy));
24+
router.get('/posts', api.http(api.posts.browse));
25+
router.post('/posts', api.http(api.posts.add));
26+
router.get('/posts/:id', api.http(api.posts.read));
27+
router.get('/posts/slug/:slug', api.http(api.posts.read));
28+
router.put('/posts/:id', api.http(api.posts.edit));
29+
router.del('/posts/:id', api.http(api.posts.destroy));
30+
1631
// ## Settings
17-
router.get('/ghost/api/v0.1/settings/', api.http(api.settings.browse));
18-
router.get('/ghost/api/v0.1/settings/:key/', api.http(api.settings.read));
19-
router.put('/ghost/api/v0.1/settings/', api.http(api.settings.edit));
32+
router.get('/settings', api.http(api.settings.browse));
33+
router.get('/settings/:key', api.http(api.settings.read));
34+
router.put('/settings', api.http(api.settings.edit));
35+
2036
// ## Users
21-
router.get('/ghost/api/v0.1/users/', api.http(api.users.browse));
22-
router.get('/ghost/api/v0.1/users/:id/', api.http(api.users.read));
23-
router.put('/ghost/api/v0.1/users/password/', api.http(api.users.changePassword));
24-
router.put('/ghost/api/v0.1/users/:id/', api.http(api.users.edit));
25-
router.post('/ghost/api/v0.1/users/', api.http(api.users.invite));
26-
router['delete']('/ghost/api/v0.1/users/:id/', api.http(api.users.destroy));
37+
router.get('/users', api.http(api.users.browse));
38+
router.get('/users/:id', api.http(api.users.read));
39+
router.get('/users/slug/:slug', api.http(api.users.read));
40+
router.get('/users/email/:email', api.http(api.users.read));
41+
router.put('/users/password', api.http(api.users.changePassword));
42+
router.put('/users/:id', api.http(api.users.edit));
43+
router.post('/users', api.http(api.users.invite));
44+
router.del('/users/:id', api.http(api.users.destroy));
2745

2846
// ## Tags
29-
router.get('/ghost/api/v0.1/tags/', api.http(api.tags.browse));
47+
router.get('/tags', api.http(api.tags.browse));
48+
49+
// ## Slugs
50+
router.get('/slugs/:type/:name', api.http(api.slugs.generate));
51+
3052
// ## Themes
31-
router.get('/ghost/api/v0.1/themes/', api.http(api.themes.browse));
32-
router.put('/ghost/api/v0.1/themes/:name', api.http(api.themes.edit));
53+
router.get('/themes', api.http(api.themes.browse));
54+
router.put('/themes/:name', api.http(api.themes.edit));
55+
3356
// ## Notifications
34-
router.get('/ghost/api/v0.1/notifications/', api.http(api.notifications.browse));
35-
router.post('/ghost/api/v0.1/notifications/', api.http(api.notifications.add));
36-
router['delete']('/ghost/api/v0.1/notifications/:id', api.http(api.notifications.destroy));
57+
router.get('/notifications', api.http(api.notifications.browse));
58+
router.post('/notifications', api.http(api.notifications.add));
59+
router.del('/notifications/:id', api.http(api.notifications.destroy));
60+
3761
// ## DB
38-
router.get('/ghost/api/v0.1/db/', api.http(api.db.exportContent));
39-
router.post('/ghost/api/v0.1/db/', middleware.busboy, api.http(api.db.importContent));
40-
router['delete']('/ghost/api/v0.1/db/', api.http(api.db.deleteAllContent));
62+
router.get('/db', api.http(api.db.exportContent));
63+
router.post('/db', middleware.busboy, api.http(api.db.importContent));
64+
router.del('/db', api.http(api.db.deleteAllContent));
65+
4166
// ## Mail
42-
router.post('/ghost/api/v0.1/mail', api.http(api.mail.send));
43-
router.post('/ghost/api/v0.1/mail/test', function (req, res) {
67+
router.post('/mail', api.http(api.mail.send));
68+
router.post('/mail/test', function (req, res) {
4469
api.settings.read('email').then(function (result) {
4570
// attach the to: address to the request body so that it is available
4671
// to the http api handler
@@ -51,15 +76,13 @@ apiRoutes = function (middleware) {
5176
api.http(api.mail.sendTest)(req, res);
5277
});
5378
});
54-
// ## Slugs
55-
router.get('/ghost/api/v0.1/slugs/:type/:name', api.http(api.slugs.generate));
56-
// ## Authentication
57-
router.post('/ghost/api/v0.1/authentication/passwordreset', api.http(api.authentication.generateResetToken));
58-
router.put('/ghost/api/v0.1/authentication/passwordreset', api.http(api.authentication.resetPassword));
5979

60-
router.post('/ghost/api/v0.1/authentication/invitation', api.http(api.authentication.acceptInvitation));
6180

62-
router.post('/ghost/api/v0.1/authentication/token',
81+
// ## Authentication
82+
router.post('/authentication/passwordreset', api.http(api.authentication.generateResetToken));
83+
router.put('/authentication/passwordreset', api.http(api.authentication.resetPassword));
84+
router.post('/authentication/invitation', api.http(api.authentication.acceptInvitation));
85+
router.post('/authentication/token',
6386
middleware.addClientSecret,
6487
middleware.authenticateClient,
6588
middleware.generateAccessToken

core/server/routes/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ var api = require('./api'),
33
frontend = require('./frontend');
44

55
module.exports = {
6+
apiBaseUri: '/ghost/api/v0.1/',
67
api: api,
78
admin: admin,
89
frontend: frontend

core/test/functional/routes/api/posts_test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ describe('Post API', function () {
201201
});
202202

203203
it('can retrieve a post by slug', function (done) {
204-
request.get(testUtils.API.getApiQuery('posts/welcome-to-ghost/'))
204+
request.get(testUtils.API.getApiQuery('posts/slug/welcome-to-ghost/'))
205205
.set('Authorization', 'Bearer ' + accesstoken)
206206
.expect('Content-Type', /json/)
207207
.end(function (err, res) {
@@ -542,7 +542,7 @@ describe('Post API', function () {
542542
return done(err);
543543
}
544544

545-
545+
546546
var unpublishedPost = res.body;
547547
// Unpublishing a post should send x-cache-invalidate headers
548548
_.has(res.headers, 'x-cache-invalidate').should.equal(true);

0 commit comments

Comments
 (0)