254 lines
5.3 KiB
Plaintext
254 lines
5.3 KiB
Plaintext
---
|
|
title: Blog API From Scratch
|
|
label: Blog API
|
|
order: 20
|
|
---
|
|
|
|
In this guide, we will be creating a Blog API from scratch.
|
|
|
|
Prerequisites:
|
|
|
|
- Node
|
|
- npm or yarn
|
|
- MongoDB server
|
|
|
|
## Initial Setup
|
|
|
|
Let's get started by creating a project in a blank directory
|
|
|
|
```sh
|
|
yarn init -y
|
|
```
|
|
|
|
We then will install Payload and Express
|
|
|
|
```sh
|
|
yarn add payload express
|
|
```
|
|
|
|
### Server
|
|
|
|
Create a file named `server.js` in the root folder with the following contents
|
|
|
|
```js
|
|
const express = require('express');
|
|
const app = express();
|
|
|
|
app.listen(3000, async () => {
|
|
console.log('Express is now listening for incoming connections on port 3000.');
|
|
});
|
|
```
|
|
|
|
This is a basic Express application. Now let's pull in Payload and fill in the `init` parameters. `secret` and `mongoURL` can be changed as needed.
|
|
|
|
```js
|
|
const express = require('express');
|
|
const payload = require('payload'); // highlight-line
|
|
|
|
const app = express();
|
|
|
|
// highlight-start
|
|
payload.init({
|
|
secret: 'SECRET_KEY',
|
|
mongoURL: 'mongodb://localhost/payload-blog',
|
|
express: app,
|
|
})
|
|
// highlight-end
|
|
|
|
app.listen(3000, async () => {
|
|
console.log('Express is now listening for incoming connections on port 3000.');
|
|
});
|
|
```
|
|
|
|
### Payload Configuration
|
|
|
|
Next, let's get some basics put into our `payload.config.js` file
|
|
|
|
```js
|
|
module.exports = {
|
|
serverURL: 'http://localhost:3000',
|
|
collections: [],
|
|
}
|
|
```
|
|
|
|
#### Collections
|
|
|
|
We'll need a few different collections for our blog:
|
|
|
|
- Posts
|
|
- Categories
|
|
- Tags
|
|
|
|
The Posts will have the ability to have a single category and multiple tags
|
|
|
|
Let's create a `collections` directory and create a `.js` file for each
|
|
|
|
```js:title=Posts.js
|
|
module.exports = {
|
|
slug: 'posts',
|
|
labels: {
|
|
singular: 'Post',
|
|
plural: 'Posts',
|
|
},
|
|
admin: {
|
|
useAsTitle: 'title',
|
|
},
|
|
fields: [
|
|
{
|
|
name: 'title',
|
|
label: 'Title',
|
|
type: 'text'
|
|
},
|
|
{
|
|
name: 'content',
|
|
label: 'Content',
|
|
type: 'textarea',
|
|
},
|
|
{
|
|
name: 'category',
|
|
label: 'Category',
|
|
type: 'relationship',
|
|
relationTo: 'categories', // Categories Slug // highlight-line
|
|
},
|
|
{
|
|
name: 'tags',
|
|
label: 'Tags',
|
|
type: 'relationship',
|
|
relationTo: 'tags', // Tags Slug // highlight-line
|
|
hasMany: true, // Allow multiple tags per post
|
|
},
|
|
]
|
|
};
|
|
```
|
|
|
|
```js:title=Categories.js
|
|
module.exports = {
|
|
slug: 'categories',
|
|
labels: {
|
|
singular: 'Category',
|
|
plural: 'Categories',
|
|
},
|
|
admin: {
|
|
useAsTitle: 'name',
|
|
},
|
|
fields: [
|
|
{
|
|
name: 'name',
|
|
label: 'Name',
|
|
type: 'text',
|
|
},
|
|
],
|
|
};
|
|
```
|
|
|
|
```js:title=Tags.js
|
|
module.exports = {
|
|
slug: 'tags',
|
|
labels: {
|
|
singular: 'Tag',
|
|
plural: 'Tags',
|
|
},
|
|
admin: {
|
|
useAsTitle: 'name',
|
|
},
|
|
fields: [
|
|
{
|
|
name: 'name',
|
|
label: 'Name',
|
|
type: 'text',
|
|
},
|
|
],
|
|
};
|
|
```
|
|
|
|
Once these are created, we can pull them into the `collections` array in our `payload.config.js`
|
|
|
|
```js:title=payload.config.js
|
|
const Admins = require('./collections/Admins');
|
|
// highlight-start
|
|
const Posts = require('./collections/Posts');
|
|
const Categories = require('./collections/Categories');
|
|
const Tags = require('./collections/Tags');
|
|
// highlight-end
|
|
|
|
module.exports = {
|
|
serverURL: 'http://localhost:3000',
|
|
admin: {
|
|
user: 'admins',
|
|
},
|
|
collections: [
|
|
Admins,
|
|
// highlight-start
|
|
Posts,
|
|
Categories,
|
|
Tags
|
|
// highlight-end
|
|
],
|
|
}
|
|
```
|
|
|
|
### Create Content
|
|
|
|
**TODO: Should a guide like this use the Admin interface or `curl`?**
|
|
|
|
Navigate to the admin interface at `http://localhost:3000/admin` and create your first user.
|
|
|
|
Then create some Categories, Tags, and a Post.
|
|
|
|
Let's use `curl` to quickly create some data. The following commands will create 2 tags and 1 category.
|
|
|
|
```sh
|
|
curl -H "Content-Type: application/json" -X POST -d '{"name": "JavaScript"}' http://localhost:3000/api/tags
|
|
curl -H "Content-Type: application/json" -X POST -d '{"name": "TypeScript"}' http://localhost:3000/api/tags
|
|
curl -H "Content-Type: application/json" -X POST -d '{"name": "Code"}' http://localhost:3000/api/categories
|
|
```
|
|
|
|
We'll then make a request to create a Post, this will inclue a relationship to the category and tags created previously.
|
|
|
|
TODO: Somehow retrieve tag and category IDs then include them in a request to create a Post
|
|
|
|
Once complete, navigate to `http://localhost:3000/api/posts`, and you should see something similar to the following:
|
|
|
|
```js
|
|
{
|
|
"docs": [
|
|
{
|
|
"tags": [
|
|
{
|
|
"name": "TypeScript",
|
|
"createdAt": "2020-11-13T11:48:05.993Z",
|
|
"updatedAt": "2020-11-13T11:48:05.993Z",
|
|
"id": "5fae72758315da656fb3a8f0"
|
|
},
|
|
{
|
|
"name": "JavaScript",
|
|
"createdAt": "2020-11-13T11:48:00.064Z",
|
|
"updatedAt": "2020-11-13T11:48:00.064Z",
|
|
"id": "5fae72708315da656fb3a8ef"
|
|
}
|
|
],
|
|
"title": "My Title",
|
|
"content": "This is some content",
|
|
"category": {
|
|
"name": "Code",
|
|
"createdAt": "2020-11-13T11:48:10.351Z",
|
|
"updatedAt": "2020-11-13T11:48:36.358Z",
|
|
"id": "5fae727a8315da656fb3a8f1"
|
|
},
|
|
"createdAt": "2020-11-13T11:50:14.312Z",
|
|
"updatedAt": "2020-11-13T11:50:14.312Z",
|
|
"id": "5fae72f68e314b67609e05d1"
|
|
}
|
|
],
|
|
"totalDocs": 1,
|
|
"limit": 10,
|
|
"totalPages": 1,
|
|
"page": 1,
|
|
"pagingCounter": 1,
|
|
"hasPrevPage": false,
|
|
"hasNextPage": false,
|
|
"prevPage": null,
|
|
"nextPage": null
|
|
}
|
|
```
|