Skip to content

Commit

Permalink
docs: Various documentation improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelbromley committed Oct 13, 2021
1 parent 6c14782 commit 6bc01aa
Show file tree
Hide file tree
Showing 12 changed files with 131 additions and 23 deletions.
4 changes: 4 additions & 0 deletions docs/content/developer-guide/channels.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ Use-cases of Channels include:
* Creating distinct rules and inventory for different sales channels such as Amazon.
* Specialized stores offering a subset of the main inventory.

## How to set the channel when using the GraphQL API

To specify which channel to use when making an API call, set the `'vendure-token'` header to match the token of the desired Channel.

## Multi-Tenant (Marketplace) Support

Channels can also be used to implement a multi-tenant or marketplace application. In such a setup, each merchant would have their own dedicated Channel and would be granted permissions on that Channel only.
18 changes: 18 additions & 0 deletions docs/content/developer-guide/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,24 @@ For a production Vendure server, there are a few security-related points to cons
```
* Consider using [helmet](https://github.com/helmetjs/helmet) as middleware (add to the `apiOptions.middleware` array) to handle security-related headers.

## Serverless / multi-instance deployments

Vendure supports running in a serverless or multi-instance (horizontally scaled) environment. The key consideration in configuring Vendure for this scenario is to ensure that any persistent state is managed externally from the Node process, and is shared by all instances. Namely:

* The JobQueue should be stored externally using the [DefaultJobQueuePlugin]({{< relref "default-job-queue-plugin" >}}) (which stores jobs in the database) or the [BullMQJobQueuePlugin]({{< relref "bull-mqjob-queue-plugin" >}}) (which stores jobs in Redis), or some other custom JobQueueStrategy.
* A custom [SessionCacheStrategy]({{< relref "session-cache-strategy" >}}) must be used which stores the session cache externally (such as in the database or Redis), since the default strategy stores the cache in-memory and will cause inconsistencies in multi-instance setups.
* When using cookies to manage sessions, make sure all instances are using the _same_ cookie secret:
```TypeScript
const config: VendureConfig = {
authOptions: {
cookieOptions: {
secret: 'some-secret'
}
}
}
```
* Channel and Zone data gets cached in-memory as this data is used in virtually every request. The cache time-to-live defaults to 30 seconds, which is probably fine for most cases, but it can be configured in the [EntityOptions]({{< relref "entity-options" >}}#channelcachettl).

## Health/Readiness Checks

If you wish to deploy with Kubernetes or some similar system, you can make use of the health check endpoints.
Expand Down
33 changes: 15 additions & 18 deletions docs/content/storefront/building-a-storefront/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,32 @@ The storefront is the application which customers use to buy things from your st

As a headless server, Vendure provides a GraphQL API and Admin UI app, but no storefront. The key advantage of the headless model is that the storefront (or indeed, any number of client applications) can be developed completely independently of the server. This flexibility comes at the cost of having to build and maintain your own storefront.

Essentially, you can use **any technology** to build your storefront. Here are some suggestions you may wish to investigate:
Luckily there are some projects that can help you get your storefront up-and-running quickly:

## Angular / Vendure Storefront

{{< figure src="./vendure-storefront-screenshot-01.jpg" >}}

This is an example storefront PWA application built with Angular. If you have Angular experience you may wish to use this as the basis of your own storefront implementation.

A live demo can be found here: [demo.vendure.io/storefront/](https://demo.vendure.io/storefront/)
## Vue Storefront

Keep up with development here: [github.com/vendure-ecommerce/storefront](https://github.com/vendure-ecommerce/storefront)
{{< figure src="./vue-storefront-logo.png" >}}

## Next.js
[Vue Storefront](https://www.vuestorefront.io/) is a popular backend-agnostic storefront PWA solution and they offer an official [Vue Storefront Vendure integration](https://docs.vuestorefront.io/vendure/).

[Next.js](https://nextjs.org/) is a popular React-based framework which many Vendure developers have chosen as the basis of their storefront application. The team behind Next.js are also working on an e-commerce-specific solution, [Next.js Commerce](https://nextjs.org/commerce), which is currently under development but is worth keeping an eye on.
For step-by-step instructions see our [Vue Storefront integration blog post]({{< relref "/blog/2021-10-13-announcing-vendure-1-3/index.md" >}}).

## Vue / Nuxt
## Next.js Commerce

{{< figure src="./vercel-commerce-screenshot.webp" >}}

[Nuxt](https://nuxtjs.org/) is a framework based on [Vue](https://vuejs.org/) with a focus on developer experience and has support for PWA, server-side rendering and static content generation.
[Next.js](https://nextjs.org/) is a popular React-based framework which many Vendure developers have chosen as the basis of their storefront application. The team behind Next.js have created an e-commerce-specific solution, [Next.js Commerce](https://nextjs.org/commerce), and it includes an official [Vendure integration](https://github.com/vercel/commerce/tree/main/framework/vendure)

[Next.js Commerce Vendure integration demo](https://vendure.vercel.store/)

## Vue Storefront

[Vue Storefront](https://www.vuestorefront.io/) is a popular backend-agnostic storefront PWA solution. They offer documentation on connecting their frontend application with a custom backend such as Vendure: https://github.com/DivanteLtd/vue-storefront-integration-sdk
## Angular Demo Storefront

## Gatsby
{{< figure src="./vendure-storefront-screenshot-01.jpg" >}}

[Gatsby](https://www.gatsbyjs.org/) is a popular React-based static site generator. We have developed a Gatsby-based storefront app: [vendure-ecommerce/gatsby-storefront](https://github.com/vendure-ecommerce/gatsby-storefront). This is a minimal proof-of-concept which can be used as the starting point for your own Gatsby-based storefront.
This is an example storefront PWA application built with Angular. If you have Angular experience you may wish to use this as the basis of your own storefront implementation.

## Svelte / Sapper
A live demo can be found here: [demo.vendure.io/storefront/](https://demo.vendure.io/storefront/)

[Sapper](https://sapper.svelte.dev/) is a framework based on [Svelte](https://svelte.dev/), and focuses on high-performance and supports server-rendering.
Keep up with development here: [github.com/vendure-ecommerce/storefront](https://github.com/vendure-ecommerce/storefront)
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion packages/common/src/shared-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ export type JsonCompatible<T> = {

/**
* @description
* A type describing the shape of a paginated list response.
* A type describing the shape of a paginated list response. In Vendure, almost all list queries
* (`products`, `collections`, `orders`, `customers` etc) return an object of this type.
*
* @docsCategory common
*/
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/config/vendure-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,7 @@ export interface JobQueueOptions {
* Options relating to the internal handling of entities.
*
* @since 1.3.0
* @docsCategory configuration
*/
export interface EntityOptions {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Job } from '../job';
* {@link JobBuffer}.
*
* @since 1.3.0
* @docsCategory job-queue
*/
export interface JobBufferStorageStrategy extends InjectableStrategy {
/**
Expand Down
21 changes: 21 additions & 0 deletions packages/core/src/job-queue/job-buffer/job-buffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,27 @@ import { JobData } from '../types';
* }
* ```
*
* A JobBuffer is used by adding it to the {@link JobQueueService}, at which point it will become active
* and start collecting jobs.
*
* At some later point, the buffer can be flushed, causing the buffered jobs to be passed through the
* `reduce()` method and sent to the job queue.
*
* @example
* ```TypeScript
* const collectionBuffer = new CollectionJobBuffer();
*
* await this.jobQueueService.addBuffer(collectionBuffer);
*
* // Here you can perform some work which would ordinarily
* // trigger the 'apply-collection-filters' job, such as updating
* // collection filters or changing ProductVariant prices.
*
* await this.jobQueueService.flush(collectionBuffer);
*
* await this.jobQueueService.removeBuffer(collectionBuffer);
* ```
*
* @docsCategory JobQueue
* @since 1.3.0
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,51 @@ import { SqlJobQueueStrategy } from './sql-job-queue-strategy';
* @docsPage DefaultJobQueuePlugin
*/
export interface DefaultJobQueueOptions {
/**
* @description
* The interval in ms between polling the database for new jobs. If many job queues
* are active, the polling may cause undue load on the database, in which case this value
* should be increased to e.g. 1000.
*
* @description 200
*/
pollInterval?: number | ((queueName: string) => number);
/**
* @description
* How many jobs from a given queue to process concurrently.
*
* @default 1
*/
concurrency?: number;
/**
* @description
* The strategy used to decide how long to wait before retrying a failed job.
*
* @default () => 1000
*/
backoffStrategy?: BackoffStrategy;
/**
* @description
* When a job is added to the JobQueue using `JobQueue.add()`, the calling
* code may specify the number of retries in case of failure. This option allows
* you to override that number and specify your own number of retries based on
* the job being added.
*
* @example
* ```TypeScript
* setRetries: (queueName, job) => {
* if (queueName === 'send-email') {
* // Override the default number of retries
* // for the 'send-email' job because we have
* // a very unreliable email service.
* return 10;
* }
* return job.retries;
* }
* ```
* @param queueName
* @param job
*/
setRetries?: (queueName: string, job: Job) => number;
/**
* @description
Expand Down Expand Up @@ -109,7 +151,7 @@ export interface DefaultJobQueueOptions {
* // A default delay for all other queues
* return 1000;
* },
* retries: (queueName, job) => {
* setRetries: (queueName, job) => {
* if (queueName === 'send-email') {
* // Override the default number of retries
* // for the 'send-email' job because we have
Expand Down
16 changes: 13 additions & 3 deletions packages/elasticsearch-plugin/src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,8 @@ export interface ElasticsearchOptions {
* Elasticsearch index and expose that data via the SearchResult GraphQL type,
* adding a new `customMappings` field.
*
* The `graphQlType` property may be one of `String`, `Int`, `Float`, `Boolean`, or list
* versions thereof (`[String!]` etc) and
* can be appended with a `!` to indicate non-nullable fields.
* The `graphQlType` property may be one of `String`, `Int`, `Float`, `Boolean`, `ID` or list
* versions thereof (`[String!]` etc) and can be appended with a `!` to indicate non-nullable fields.
*
* This config option defines custom mappings which are accessible when the "groupByProduct"
* input options is set to `true`.
Expand Down Expand Up @@ -464,6 +463,17 @@ export interface SearchConfig {
* @description
* Sets `script_fields` inside the elasticsearch body which allows returning a script evaluation for each hit.
*
* The script field definition consists of three properties:
*
* * `graphQlType`: This is the type that will be returned when this script field is queried
* via the GraphQL API. It may be one of `String`, `Int`, `Float`, `Boolean`, `ID` or list
* versions thereof (`[String!]` etc) and can be appended with a `!` to indicate non-nullable fields.
* * `context`: determines whether this script field is available when grouping by product. Can be
* `product`, `variant` or `both`.
* * `scriptFn`: This is the function to run on each hit. Should return an object with a `script` property,
* as covered in the
* [Elasticsearch script fields docs](https://www.elastic.co/guide/en/elasticsearch/reference/7.15/search-fields.html#script-fields)
*
* @example
* ```TypeScript
* extendSearchInputType: {
Expand Down
13 changes: 13 additions & 0 deletions packages/job-queue-plugin/src/bullmq/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,19 @@ export interface BullMQPluginOptions {
* you to override that number and specify your own number of retries based on
* the job being added.
*
* @example
* ```TypeScript
* setRetries: (queueName, job) => {
* if (queueName === 'send-email') {
* // Override the default number of retries
* // for the 'send-email' job because we have
* // a very unreliable email service.
* return 10;
* }
* return job.retries;
* }
* ```
*
* @since 1.3.0
*/
setRetries?: (queueName: string, job: Job) => number;
Expand Down

0 comments on commit 6bc01aa

Please sign in to comment.