Back

Reading and Writing Data Using the Ghost API

Aug 13, 20246 minute read

Hey there, fellow JavaScript devs! Ready to dive into the world of Ghost API integration? Let's get our hands dirty with some code and learn how to sync data for a user-facing integration. Buckle up!

Setting Up Ghost API Access

First things first, you'll need to grab your API credentials. Head over to your Ghost admin panel, navigate to "Integrations," and create a new custom integration. You'll get a shiny new API key and secret. Guard these with your life!

Now, let's install the Ghost API client:

npm install @tryghost/content-api

Set it up like this:

const GhostContentAPI = require('@tryghost/content-api'); const api = new GhostContentAPI({ url: 'https://your-ghost-site.com', key: 'YOUR_CONTENT_API_KEY', version: 'v3' });

Reading Data from Ghost

Time to fetch some data! Here's how you can grab your recent posts:

async function getRecentPosts() { try { const posts = await api.posts .browse({limit: 5, include: 'tags,authors'}); return posts; } catch (error) { console.error(error); } }

Easy peasy, right? You can also fetch authors, tags, and more. Just check out the Ghost API docs for all the juicy details.

Writing Data to Ghost

Now, let's create a new post:

async function createPost(title, content, tags) { try { const newPost = await api.posts.add({ title, content, tags: tags.map(name => ({name})), status: 'published' }, {source: 'html'}); return newPost; } catch (error) { console.error(error); } }

Syncing Data for User-Facing Integration

When it comes to syncing, you'll want to implement a strategy that works for your use case. Here's a simple example of syncing user-generated content:

async function syncUserContent(userId, content) { try { const existingPost = await api.posts.read({slug: `user-${userId}`}); if (existingPost) { return await api.posts.edit({ id: existingPost.id, content: existingPost.content + '\n\n' + content }); } else { return await createPost(`User ${userId} Content`, content, ['user-generated']); } } catch (error) { console.error(error); } }

Error Handling and Rate Limiting

Don't forget to handle those pesky errors and respect rate limits:

async function fetchWithRetry(apiCall, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { try { return await apiCall(); } catch (error) { if (error.response && error.response.status === 429) { const retryAfter = error.response.headers['retry-after'] || 5; await new Promise(resolve => setTimeout(resolve, retryAfter * 1000)); } else if (i === maxRetries - 1) { throw error; } } } }

Webhooks for Real-Time Updates

Want to keep your app up-to-date in real-time? Set up webhooks in your Ghost admin panel and handle them like this:

app.post('/ghost-webhook', (req, res) => { const event = req.body; if (event.event === 'post.published') { // Do something with the new post console.log('New post published:', event.post.current.title); } res.sendStatus(200); });

Best Practices and Optimization

Remember to cache aggressively, batch your operations when possible, and minimize API calls. Your future self (and your users) will thank you!

const cache = new Map(); async function getCachedPosts() { if (!cache.has('recentPosts') || Date.now() - cache.get('recentPosts').timestamp > 300000) { const posts = await getRecentPosts(); cache.set('recentPosts', { data: posts, timestamp: Date.now() }); } return cache.get('recentPosts').data; }

And there you have it! You're now armed with the knowledge to read and write data using the Ghost API like a pro. Go forth and build amazing integrations! Remember, the Ghost API documentation is your best friend for diving deeper into specific features. Happy coding!