Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(IN-3860): Update integrations-related docs #7075

Merged
merged 20 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Creating an API Client
WojtekTheWebDev marked this conversation as resolved.
Show resolved Hide resolved



The API client is used by the server middleware to create a server-to-server communication with your custom backend.

## Creating the integration client
Expand All @@ -12,7 +10,7 @@ First, you should create the `index.server.ts` file. It will be the entry point

```ts
// index.server.ts
import { apiClientFactory } from '@vue-storefront/middleware';
import { apiClientFactory } from "@vue-storefront/middleware";

const onCreate = (settings: any) => {
// TODO: create a client here and return it with the integration configuration
Expand All @@ -32,7 +30,7 @@ The `onCreate` function is called when the server middleware is initialized. It

The `api` object is a set of functions that will be available in the integration client.

Now, let's create the client.
Now, let's create the client.

:::tip
In the following example we used the `axios` library to create a client. However, you can use any client that you suits your needs.
WojtekTheWebDev marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -57,9 +55,9 @@ You should use the `MiddlewareConfig` interface in the `onCreate` function.

```ts
// index.server.ts
import { apiClientFactory } from '@vue-storefront/middleware';
import axios from 'axios';
import { MiddlewareConfig } from './types/config';
import { apiClientFactory } from "@vue-storefront/middleware";
import axios from "axios";
import { MiddlewareConfig } from "./types/config";

const buildClient = () => {
WojtekTheWebDev marked this conversation as resolved.
Show resolved Hide resolved
const axiosInstance = axios.create();
Expand Down Expand Up @@ -87,16 +85,11 @@ The server middleware can be initialized now, but it does not contain any API fu

WojtekTheWebDev marked this conversation as resolved.
Show resolved Hide resolved
```ts
// types/context/index.ts
import { IntegrationContext } from '@vue-storefront/middleware';
import { AxiosInstance } from 'axios';
import { MiddlewareConfig } from '../config';
import { IntegrationContext } from "@vue-storefront/middleware";
import { AxiosInstance } from "axios";
import { MiddlewareConfig } from "../config";

/**
* All available API Endpoints without first argument - `context`, because this prop is set automatically.
*/
export type ContextualizedEndpoints = {
[T in keyof Endpoints]: Endpoints[T] extends (x: any, ...args: infer P) => infer R ? (...args: P) => R : never;
};
export type TODO = any;

/**
* Runtime integration context, which includes API client instance, settings, and endpoints that will be passed via middleware server.
Expand All @@ -105,71 +98,89 @@ export type ContextualizedEndpoints = {
export type MyIntegrationIntegrationContext = IntegrationContext<
AxiosInstance, // HTTP client instance
MiddlewareConfig,
ContextualizedEndpoints
TODO
>;

/**
* Global context of the application which includes runtime integration context.
**/
export interface Context {
// This property is named `myIntegration`, but you should use your integration name in here.
$myIntegration: MyIntegrationIntegrationContext;
}
```

The `ContextualizedEndpoints` type is a set of API functions without the `context` argument. It's necessary for the `IntegrationContext` type. It also requires the type of client used in the integration and the type of integration configuration.
Now, you can create the first API method - an `exampleEndpoint` function.

```ts
// api/exampleEndpoint/index.ts
import { MyIntegrationIntegrationContext, TODO } from "../../types";

export const exampleEndpoint = async (
context: MyIntegrationIntegrationContext,
params: TODO
) => {
console.log("exampleEndpoint has been called");

The `Context` type is the global context of the application. It's used by api-client methods to access the integration client and the configuration.
// Example request could look like this:
// return await context.client.get(`example-url?id=${params.id}`);
return Promise.resolve({ success: true });
};
```

Now you can add the interface for the API functions.
You should also export the `exampleEndpoint` function in the `api/index.ts` file.

```ts
// types/api/index.ts
import { MyIntegrationContext } from '../config';
// api/index.ts
export * from "./exampleEndpoint";
```

type TODO = any;
Then, let's create the `Endpoints` type.

/**
* Definition of all API-client methods available in {@link https://docs.vuestorefront.io/v2/advanced/context.html#context-api | context}.
*/
export interface Endpoints {
/**
* Here you can find an example endpoint definition. Based on this example, you should define how your endpoint will look like.
* This description will appear in the API extractor, so try to document all endpoints added here.
*/
exampleEndpoint: (context: MyIntegrationContext, params: TODO) => Promise<TODO>;
}
```ts
// types/api/endpoints.ts
import { WithoutContext } from "@vue-storefront/middleware";
import * as api from "../../api";

export type Endpoints = WithoutContext<typeof api>;
```

Finally, you can create the `exampleEndpoint` function.
Notice that we use the `WithoutContext` type from the `@vue-storefront/middleware` package. It's a utility type that removes the `context` parameter from the API functions.
`context` is only used in the server middleware, so it should not be included in the final interface.
WojtekTheWebDev marked this conversation as resolved.
Show resolved Hide resolved

Finally, let's add the `Endpoints` type to the `MyIntegrationIntegrationContext` interface.

```ts
// api/exampleEndpoint/index.ts
import { Endpoints } from '../../types';
// types/context/index.ts
import { IntegrationContext } from "@vue-storefront/middleware";
import { AxiosInstance } from "axios";
import { MiddlewareConfig } from "../config";
import { Endpoints } from "../api/endpoints";

export const exampleEndpoint: Endpoints['exampleEndpoint'] = async (context, params) => {
console.log('exampleEndpoint has been called');
export type TODO = any;

// Example request could look like this:
// return await context.client.get(`example-url?id=${params.id}`);
return Promise.resolve({ success: true });
};
export type MyIntegrationIntegrationContext = IntegrationContext<
AxiosInstance, // HTTP client instance
MiddlewareConfig,
Endpoints
>;
```

You should also export the `exampleEndpoint` function in the `api/index.ts` file.
Remember to export all the types in the `types/index.ts` file.

```ts
// api/index.ts
export * from './exampleEndpoint';
// types/index.ts
export * from "./config";
export * from "./context";
export * from "./api/endpoints";
```

And from `index.ts` as well.

```ts
// index.ts
export * from "./types";
```

To be able to call the `exampleEndpoint` function, you should add it to the `api` object in the `index.server.ts` file.

```ts
import { apiClientFactory } from '@vue-storefront/middleware';
import axios from 'axios';
import * as api from './api';
import { MiddlewareConfig } from './types/config';
import { apiClientFactory } from "@vue-storefront/middleware";
import axios from "axios";
import * as api from "./api";
import { MiddlewareConfig } from "./types/config";

const buildClient = () => {
const axiosInstance = axios.create();
Expand Down Expand Up @@ -207,7 +218,7 @@ This guide described the details of creating the integration, but it does not co
module.exports = {
integrations: {
boilerplate: {
location: '@vsf-enterprise/my-integration-api/server', // This should be the path to your built index.server.js file
location: "@vsf-enterprise/my-integration-api/server", // This should be the path to your built index.server.js file
configuration: {
// Add your configuration here
},
Expand All @@ -220,20 +231,22 @@ You can run the server middleware with this example script:

```js
// server.js
const { createServer } = require('@vue-storefront/middleware');
const { integrations } = require('./middleware.config');
const cors = require('cors');
const { createServer } = require("@vue-storefront/middleware");
const { integrations } = require("./middleware.config");
const cors = require("cors");

(async () => {
const app = await createServer({ integrations });
const host = process.argv[2] ?? '0.0.0.0';
const host = process.argv[2] ?? "0.0.0.0";
const port = process.argv[3] ?? 8181;
const CORS_MIDDLEWARE_NAME = 'corsMiddleware';
const CORS_MIDDLEWARE_NAME = "corsMiddleware";

const corsMiddleware = app._router.stack.find((middleware) => middleware.name === CORS_MIDDLEWARE_NAME);
const corsMiddleware = app._router.stack.find(
(middleware) => middleware.name === CORS_MIDDLEWARE_NAME
);

corsMiddleware.handle = cors({
origin: ['http://localhost:3000'],
origin: ["http://localhost:3000"],
credentials: true,
});

Expand Down
4 changes: 2 additions & 2 deletions docs/content/4.sdk/1.index.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ By utilizing the Vue Storefront SDK, you can establish a type-safe contract betw
The SDK has two components:

1. The SDK Core - the core package, `@vue-storefront/sdk`, that initializes all modules and implements the plug-in architecture
2. Modules - pluggable pieces of code as standalone packages that integrate into the core to add functionality (eg.: `@vsf-enterprise/sapcc-sdk`)
2. Modules - pluggable pieces of code as standalone packages that integrate into the core to add functionality (eg.: `middlewareModule`)

In most cases, these modules will come through our [Integrations](/integrations) - which contain both an SDK Module and an API Client (Middleware) - but you can also create your own modules.
In most cases, you would use `middlewareModule` with different configurations - but you can also create your own modules.

:card{to="/integrations" title="Integrations" description="See all of the available integrations that you can use with the SDK" icon="fluent:puzzle-cube-piece-20-filled"}

Expand Down
Loading
Loading