-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Backend customization examples collection (#1831)
* WIP * Rework content up to the custom controller * Rework the custom controller part * Add more instructions on how this page can be used * Mention FoodAdvisor in each section so that it can be read alone * Change "tutorial" file name to "examples" and rework the first sections * Rework policies and routes + comment out WIP content * Fine-tune introduction and TOC entry * Disable last update information * Fully rework the page into a whole section * Fix broken links * Add tip callouts to cross-link cookbook and reference docs * Update TOC entry for Services & Controllers so that they display nice with the "New" badge * Fix the introduction title * Remove unused inline TOC import * Simplify prereq. wording * Fix instructions wording in auth. page * Improve wording in policies page * Improve wording on routes page * Improve wording in middlewares page * Clarify the headless CMS annotation * Update docusaurus/docs/dev-docs/backend-customization/examples/services-and-controllers.md Co-authored-by: Christian <[email protected]> * Test layout tweaks on Policies page * Improve code for SubtleCallout style * Add FoodAdvisor links in policies pages when missing * Shorten SubtleCallout content for policies * Try to fix SCSS for subtle admonition in production context * Refine UI & UX * Clarify naming create action will overwrite core controller action * Add tip to controllers examples * Fix clarification for overwriting action in code example * Update services-and-controllers.md * Revert "Update services-and-controllers.md" This reverts commit 957259b. * Update docusaurus/docs/dev-docs/backend-customization/examples/middlewares.md Co-authored-by: Christian <[email protected]> * Update docusaurus/docs/dev-docs/backend-customization/examples/policies.md Co-authored-by: Christian <[email protected]> * Fix intended to → intended for * Mention front-end vs. back-end code examples difference * Reformat controllers introduction * Fix typo --------- Co-authored-by: Christian <[email protected]>
- Loading branch information
1 parent
5e538bc
commit da82728
Showing
25 changed files
with
1,489 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
docusaurus/docs/dev-docs/backend-customization/examples.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
--- | ||
title: Backend Customization Examples Cookbook | ||
description: Learn how to use the core backend features of Strapi with the FoodAdvisor deployment | ||
displayed_sidebar: devDocsSidebar | ||
pagination_prev: dev-docs/backend-customization | ||
pagination_next: dev-docs/backend-customization/examples/authentication | ||
--- | ||
|
||
# Backend customization: An examples cookbook using FoodAdvisor | ||
|
||
The present section of the documentation is intended for developers who would like to get a deeper understanding of the Strapi back end customization possibilities. | ||
|
||
The section is a collection of examples that demonstrate how the core components of the back-end server of Strapi can be used in a real-world project. Front-end code that interacts with the back end may also be part of some examples, but displayed in collapsed blocks by default since front-end code examples are not the main focus of this cookbook. | ||
|
||
Examples are meant to extend the features of [FoodAdvisor](https://github.com/strapi/foodadvisor), the official Strapi demo application. FoodAdvisor builds a ready-made restaurants directory powered by a Strapi back end (included in the `/api` folder) and renders a [Next.js](https://nextjs.org/)-powered front-end website (included in the `/client` folder). | ||
|
||
:::prerequisites | ||
- 👀 You have read the [Quick Start Guide](/dev-docs/quick-start) and/or understood that Strapi is a **headless CMS** <Annotation>A headless CMS is a Content Management System that separates the presentation layer (i.e., the front end, where content is displayed) from the back end (where content is managed).<br /><br/>Strapi is a headless CMS that provides:<ul><li>a back-end server exposing an API for your content,</li><li>and a graphical user interface, called the admin panel, to manage the content.</li></ul>The presentation layer should be handled by another framework, not by Strapi.</Annotation> that helps you create a data structure with the [Content-Type Builder](/user-docs/content-type-builder) and add some content through the [Content Manager](/user-docs/content-manager), then exposes the content through APIs. | ||
- 👀 You have read the [back-end customization introduction](/dev-docs/backend-customization) to get a general understanding of what routes, policies, middlewares, controllers, and services are in Strapi. | ||
- 👷 If you want to test and play with the code examples by yourself, ensure you have cloned the [FoodAdvisor](https://github.com/strapi/foodadvisor) repository, setup the project, and started both the front-end and back-end servers. The Strapi admin panel should be accessible from [`localhost:1337/admin`](http://localhost:1337/admin) and the Next.js-based FoodAdvisor front-end website should be running on [`localhost:3000`](http://localhost:3000). | ||
::: | ||
|
||
This section can be read from start to finish, or you might want to jump directly to a specific page to understand how a given core element from the Strapi back end can be used to solve a real-world use case example: | ||
|
||
| I want to understand… | Dedicated page | | ||
|------------|---------------| | ||
| How to authenticate my queries | [Authentication flow with JWT](/dev-docs/backend-customization/examples/authentication) | | ||
| How and when to use<br />custom controllers and services | [Custom controllers and services examples](/dev-docs/backend-customization/examples/services-and-controllers) | | ||
| How to use custom policies<br />and send custom errors | [Custom policies examples](/dev-docs/backend-customization/examples/policies) | | ||
| How to configure and use custom routes | [Custom routes examples](/dev-docs/backend-customization/examples/routes) | | ||
| How and when to use<br />custom global middlewares | [Custom middleware example](/dev-docs/backend-customization/examples/middlewares) | |
147 changes: 147 additions & 0 deletions
147
docusaurus/docs/dev-docs/backend-customization/examples/authentication.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
--- | ||
title: Authentication flow with JWT | ||
description: Learn how to authenticate REST API queries using our FoodAdvisor example | ||
displayed_sidebar: devDocsSidebar | ||
pagination_prev: dev-docs/backend-customization/examples | ||
pagination_next: dev-docs/backend-customization/examples/services-and-controllers | ||
--- | ||
|
||
|
||
# Examples cookbook: Authentication flow with JWT | ||
|
||
:::prerequisites | ||
This page is part of the back end customization examples cookbook. Please ensure you've read its [introduction](/dev-docs/backend-customization/examples). | ||
::: | ||
|
||
**💭 Context:** | ||
|
||
Out of the box, the front-end website of [FoodAdvisor](https://github.com/strapi/foodadvisor) does not provide any log in functionality. Logging in is done by accessing Strapi's admin panel at [`localhost:1337/admin`](http://localhost:1337/admin`). | ||
|
||
<SideBySideContainer> | ||
|
||
<SideBySideColumn> | ||
|
||
Let's add a basic login page to the front-end, [Next.js](https://nextjs.org/)-powered website included in the `/client` folder of FoodAdvisor. The login page will be accessible at [`localhost:3000/auth/login`](http://localhost:3000/auth/login) and contain a typical email/password login form. This will allow programmatically authenticating API requests sent to Strapi. | ||
|
||
</SideBySideColumn> | ||
|
||
<SideBySideColumn> | ||
|
||
<figure style={{ width: '100%', margin: '0' }}> | ||
<img src="/img/assets/backend-customization/tutorial-auth-flow.png" alt="Example login page" /> | ||
<em><figcaption style={{ fontSize: '12px' }}>A possible example of a login form on the front-end website of FoodAdvisor</figcaption></em> | ||
</figure> | ||
|
||
|
||
</SideBySideColumn> | ||
</SideBySideContainer> | ||
|
||
<SideBySideContainer> | ||
<SideBySideColumn> | ||
|
||
**🎯 Goal**: | ||
|
||
Create a front-end component to: | ||
|
||
1. to display a login form, | ||
2. send a request to the `/auth/local` route of the Strapi back-end server to authenticate, | ||
3. get a [JSON Web Token](https://en.wikipedia.org/wiki/JSON_Web_Token) (JWT), | ||
4. and store the JWT into the [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) property of your browser for later retrieval and authentication of our requests. | ||
|
||
</SideBySideColumn> | ||
|
||
<SideBySideColumn> | ||
|
||
<SubtleCallout title="Related concept"> | ||
|
||
Additional information about JWT authentication can be found in the [Users & Permissions plugin](/dev-docs/plugins/users-permissions) documentation. | ||
|
||
</SubtleCallout> | ||
|
||
</SideBySideColumn> | ||
</SideBySideContainer> | ||
|
||
**🧑💻 Code example:** | ||
|
||
To achieve this, in the `/client` folder of the [FoodAdvisor](https://github.com/strapi/foodadvisor) project, you could create a `pages/auth/login.js` file that contains the following example code. Highlighted lines show the request sent to the `/auth/local` route provided by Strapi's Users & Permissions plugin: | ||
|
||
```jsx title="/client/pages/auth/login.js" {21-27} | ||
|
||
import React from 'react'; | ||
import { useFormik } from 'formik'; | ||
import { Button, Input } from '@nextui-org/react'; | ||
import Layout from '@/components/layout'; | ||
import { getStrapiURL } from '@/utils'; | ||
|
||
const Login = () => { | ||
const { handleSubmit, handleChange } = useFormik({ | ||
initialValues: { | ||
identifier: '', | ||
password: '', | ||
}, | ||
onSubmit: async (values) => { | ||
/** | ||
* API URLs in Strapi are by default prefixed with /api, | ||
* but because the API prefix can be configured | ||
* with the rest.prefix property in the config/api.js file, | ||
* we use the getStrapiURL() method to build the proper full auth URL. | ||
**/ | ||
const res = await fetch(getStrapiURL('/auth/local'), { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify(values), | ||
}); | ||
/** | ||
* Gets the JWT from the server response | ||
*/ | ||
const { jwt } = await res.json(); | ||
/** | ||
* Stores the JWT in the localStorage of the browser. | ||
* A better implementation would be to do this with an authentication context provider | ||
* or something more sophisticated, but it's not the purpose of this tutorial. | ||
*/ | ||
localStorage.setItem('token', jwt); | ||
}, | ||
}); | ||
/** | ||
* The following code renders a basic login form | ||
* accessible from the localhost:3000/auth/login page. | ||
*/ | ||
return ( | ||
<Layout> | ||
<div className="h-full w-full flex justify-center items-center my-24"> | ||
<form onSubmit={handleSubmit} className="flex flex-col gap-y-6 w-4/12 "> | ||
<h1 className="font-bold text-3xl mb-6">Login</h1> | ||
<Input | ||
onChange={handleChange} | ||
type="email" | ||
name="identifier" | ||
label="Email" | ||
placeholder="Enter your email" | ||
/> | ||
<Input | ||
type="password" | ||
name="password" | ||
label="Password" | ||
placeholder="Enter your password" | ||
onChange={handleChange} | ||
/> | ||
<Button type="submit" className="bg-primary rounded-md text-muted"> | ||
Login | ||
</Button> | ||
</form> | ||
</div> | ||
</Layout> | ||
); | ||
}; | ||
|
||
export default Login; | ||
``` | ||
|
||
<br /> | ||
|
||
:::strapi What's next? | ||
Learn more about how custom [services and controllers](/dev-docs/backend-customization/examples/services-and-controllers) can help you tweak a Strapi-based application. | ||
::: |
Oops, something went wrong.
da82728
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
documentation – ./
documentation-git-main-strapijs.vercel.app
docs-vercel-v4.strapi.io
documentation-strapijs.vercel.app