Code Monkey home page Code Monkey logo

service-course's People

Contributors

vtexgithubbot avatar

Watchers

 avatar

service-course's Issues

Events: Using Events as Triggers

Events: Using Events as Triggers

Introduction

With the Analytics client implemented, we want to use the Events as trigger to the requests. This means that, for every event listened, we want to perform a request to the Analytics app. So, for every X seconds, we will have a new data on Live Products.

Events

In VTEX IO, events are often used as triggers to other actions, such as sending e-mails to the final client. To implement this, we need to configure our app's client and event handler.

Activity

  1. As the Analytics client is implemented, we just need to use it in the event handler. First, in the node/event/liveUsersUpdate.ts file, import the client we implemented in the previous step:

    import { Clients } from '../clients/index'
  2. Now, we need to use the EventContext that we already configured before. Import it by updating the method. You can do so like this:

    //node/event/liveUsersUpdate.ts
    import { Clients } from './../clients/index'
    +import { EventContext } from '@vtex/api'
    
    +export async function updateLiveUsers(ctx: EventContext<Clients>) {
    ...
    }

    Note: you can also globally declare your event context in the index.ts file. If you do so, you don't need to import in every file you want to use it.

  3. Now, to use the Analytics client, do the following:

    //node/event/liveUsersUpdate.ts
    export async function updateLiveUsers(ctx: EventContext<Clients>) {
    +  const liveUsersProducts = await ctx.clients.analytics.getLiveUsers()
    +  console.log('LIVE USERS: ', liveUsersProducts)
    +  return true
    }
  4. Finally, run vtex link and for every event fired, you should see the live users retrieved from the Analytics.

    The result should be like this:
    image

Overview: Understanding the Boilerplate

Overview: Understanding the Boilerplate

Introduction

Making a brief overview of the Boilerplate, there are two directories (/node and /graphql) and the manifest.json file, which is an important file to your VTEX IO app because it will be the first communication point with the VTEX IO.

Manifest Overview

In the manifest.json file, you will find the app's name, vendor, version, and other information to pay attention to: builders, policies and dependencies. In this initial state, we have the following configurations:

  • builders: what builders your app will need. In this case, we have, so far, only the docs builder and the node builder, with their respective versions;
  • policies: if the app being built needs to access some external services or get some specific data from other places, it needs to declare so, even for external APIs. At this point, we have no specific policies yet;
  • dependencies: other VTEX IO apps your app depends on. As addressed below, for this course, we need to also link the events-example app, as it is listed as a dependency for this course app.

/node Directory Overview

All directories used over the course are already in this initial project. Most of the directories are empty and will be filled throughout the course.

  • /node/clients: both files are almost blank and are now just placeholders for the next steps.

  • /node/handlers: contains a handler that will be used in the next steps.

  • /node/utils: you will find a file containing global constants declarations (/node/constants.ts).

  • /node/index.ts: contains the initial declarations for the app functionality like the cache declaration and the service declarations, which will be incremented during the course. Here it is also possible to export resolver functions implementations (for GraphQL).

  • /node/service.json: describes your REST API and some characteristics that will directly impact your app's infrastructure attributes.
    Your service.json file will be found inside your app's /node folder, and will look similar to this:

    {
    "memory": 256,
    "timeout": 2,
    "minReplicas": 2,
    "maxReplicas": 4,
    "routes": {
      "status": {
        "path": "/_v/status/:code",
        "public": true
      }
    }
    
    Field Type Description
    memory MegaBytes. How much memory your app will have allocated. This value will be overwritten if IO detects that your app is abusing memory usage
    timeout Seconds VTEX.IO infra will abort the connection if the request time is longer than timeout
    minReplicas Integer When your app is running, how many minimum replicas will be available
    maxReplicas Integer The largest amount of replicas that will be available
    routes - Describes your app's REST routes, inside you will descibe the name, (ex: ssr), the path, and if it's public or private

/graphql Directory Overview

On this directory, you will find only the empty directories and the /graphql/schema.graphql blank file. This will all be filled throughout the course, as well.

Dependencies

For this course, this app has a dependency on the events-example app. The events-example app, when linked to your account and workspace, is responsible for providing events examples. Over the course, as we approach the events topic, there will be a more complete overview of the events-example app.

Activity

  1. For now, clone (git clone) the events-example app from this repository and run vtex link in it's directory.

Without the events-example app, this course app will not be successfully linked, as the events-example app is listed as a dependency.

After running vtex link on the events-example app, the terminal should show a healthcheck route that will be used later. It looks like this:

image

Events: Handling and receiving events

Events: Handling and receiving events

Introduction

Some interactions on VTEX IO can generate events and they can be used as triggers for actions, like the activity on this step. For now, we will use the events fired by the events-example app.

Events on VTEX IO

On VTEX IO apps, events can be fired and used to trigger actions. For example, an app that listens for order placements and triggers a confirmation e-mail. It is important to highlight that events are workspace and account bound, which means that events are only visible for the account and workspace where they were fired. Events fired on your personal workspace will only be listened to by apps linked on this same workspace.

Activity

  1. First, we are starting the event firing on the events-example app. This app will fire an event every X seconds. After running vtex link on the events-example directory, click on the healthcheck route available and a "ok" message should appear on the browser:

    image

    This healthcheck route access creates a cache context needed for the VTEX IO to fire events. Without it, the events-example app won't be able to fire the events our app is going to listen to.

  2. We need to add the event handler on the Service declaration to refer to what the app is supposed to do when listening to the event. To do so, on the /node/index.ts file, complement Service declaration:

    //node/index/ts
    
    + const THREE_SECONDS_MS = 3 * 1000
    + const CONCURRENCY = 10
    
    export default new Service<Clients, State, ParamsContext>({
      clients: {
        implementation: Clients,
        options: {
          default: {
            retries: 2,
            timeout: 10000,
          },
    +      events: {
    +        exponentialTimeoutCoefficient: 2,
    +        exponentialBackoffCoefficient: 2,
    +        initialBackoffDelay: 50,
    +        retries: 1,
    +        timeout: TREE_SECONDS_MS,
    +        concurrency: CONCURRENCY,
    +      },
    +    },
    +  },
    })

    Going by each configuration, we have the following:

    Field Type Description
    exponentialTimeoutCoefficient seconds the exponential factor by which the timeout will increase in each retry
    exponentialBackoffCoefficient seconds the exponential factor by which the backoff delay will increase in each retry
    initialBackoffDelay seconds the time the app will wait until the next retry
    retries - the maximum times the app will retry
    timeout seconds the timeout until consider a failure attempt
    concurrency - the amount of simultaneous processes the event is able to perform

    By adding this code to the Service, we are adding to the Client of this Service, the capability to handle events. At this point, we are not yet using the Client itself when handling the event.

  3. For now, we are only going to create a log when receiving an event. To create this event handler, in the /node/event directory, go to the liveUsersUpdate.ts file and do the following:

    //node/event/liveUsersUpdate.ts
    export async function updateLiveUsers() {
      console.log('EVENT HANDLER: received event')
    }
  4. Now, we need to declare in the Service the reference to this function. On the /node/index.ts file, add this code:

    ...
    + import { updateLiveUsers } from './event/liveUsersUpdate'
    ...
    
    export default new Service<Clients, State, ParamsContext>({
      ...
    +  events: {
    +    liveUsersUpdate: updateLiveUsers,
    +  },
    })
    
  5. We also need to modify the service.json file. In order to listen to events sent, we need to declare this to give the app's service this capability. You may do so, by modifying service.json file:

    //node/service.json
    {
      "memory": 128,
      "ttl": 10,
      "timeout": 10,
      "minReplicas": 2,
      "maxReplicas": 10,
      "workers": 4,
    +  "events": {
    +    "liveUsersUpdate": {
    +      "sender": "vtex.events-example",
    +      "keys": ["send-event"]
    +    }
      },
      ...
    }

    Note that we declare this by using the events resolver and the reference of the app that fires the event (declared as sender) and the event reference key (declared as keys).

  6. At last, run vtex link and wait for the event to be fired by the events-example app. When listened, the log should appear on the console, like this:

    image

Getting to know more about clients

Getting to know more about clients

Introduction

In this step, we briefly explain some clients concepts and present the clients that will be necessary for this course: analytics client and master data client. The first one will be implemented on this step, and you'll also learn how to use a client that has been already implemented in our API.

About the clients

Clients, on VTEX IO, are abstractions to other services. We tackle complexities when setting up an HTTP client, for example, so you can focus on the real value of your software. Whenever you need to setup a connection with an external API or another VTEX service, you should create a client! Some standard clients are already baked into VTEX IO, check them here.

If you already got to know more about IO services, you probably know that your implementation exports functions that receive a context object. These functions can be a resolver function to a GraphQL field, a middleware to an HTTP server or an event handler, and, in all of them, you receive a ctx (or however you wanna call it) object of type Context, and it is inside of ctx.clients where you’ll find each client.

It's possible to read more about clients concepts on this document.

Analytics client

In this course, it will be necessary to create a client that will be used to get information regarding product's number of views. The client that will be created will make a REST request in which it'll retrieve information about product views. This client needs to have a function that will be used on a handler for a specific route and this is how it can be tested.

Activity

In this step, we will implement the Analytics client. So,

  1. First, in the /node/clients/ directory, you will find a file called analytics.ts, which already has a sketch, just like the code block below. This is where you'll implement your client.

    //node/clients/analytics.ts
    import { AppClient } from '@vtex/api'
    
    export default class Analytics extends AppClient {}

    You can see in this code block that Analytics is a client that extends from AppClient because this class offers pre-configurations that assure that your client has secure communication with other parts of your app.

  2. The client needs to have a constructor and just a single method, called getLiveUsers. This method returns a promise of an array that its elements are of the type LiveUsersProduct. Using the code below, add the necessary code lines to the client:

    //node/clients/analytics.ts
    +import { AppClient, InstanceOptions, IOContext } from '@vtex/api'
    
    export default class Analytics extends AppClient {
    +  constructor(context: IOContext, options?: InstanceOptions) {
    +    super('[email protected]', context, options)
    +  }
    
    +  public getLiveUsers(): Promise<LiveUsersProduct[]> {}
    }
    
    +interface LiveUsersProduct {
    +  slug: string
    +  liveUsers: number
    +}

    The interface that is defined is going to be used as a typing on the method that we'll implement.

  3. Now it's necessary to implement the getLiveUsers method. It returns an HTTP GET request to a well-defined endpoint that is responsible for getting the data that is needed in this application. So add the following line to the method getLiveUsers:

    return this.http.get('_v/live-products')

    The method that you've just created will get the necessary data for this application: an array of objects that have two fields: slug, a string that represents the product ID and liveUsers, a number that is the quantity of users visualizing this product - which are the fields in the interface.

  4. The _v/live-products API endpoint we call above needs the app mocked-analytics to run, or your getLiveUsers method will not see anything there. In case of not running this application on appliancetheme account, you will have to install the mocked-analytics app on your workspace. To do that, you can run vtex install vtex.mocked-analytics.

  5. With your analytics client already implemented, it's necessary to declare it as one of the clients in the Clients class, so it will be accessible using the Context that we've talked about at the beginning of this step.

    So, in the node/clients/ directory, go to the file called index.ts and add a get method to the class that refers to the analytics client. It's also necessary to import the client that you created.

    // node/clients/index.ts
    + import Analytics from '../clients/analytics'
    
    export class Clients extends IOClients {
    +  public get analytics() {
    +    return this.getOrSet('analytics', Analytics)
      }
    }
  6. So as to see it working, it's possible to use getLiveUsers method inside the handler for the analytics client. Using a route that it's already defined in the project, it is possible to send a request to it and the handler responsible for this route will call the method that we created.

    Inside the node directory, there is a folder called handlers. There is already a file named analytics.ts, in which it's necessary to do two things for your test to work: get the analytics client from ctx and replace the content of ctx.body with the method mentioned before, as you can see in the code block below:

  export async function analytics(ctx: Context, next: () => Promise<any>) {
+    const {
+      clients: { analytics },
+    } = ctx
+    ctx.status = 200
-    ctx.body = 'OK'
+    ctx.body = await analytics.getLiveUsers()
+    ctx.set('cache-control', 'no-cache')
    await next()
  }
  1. Now let's test it! It's possible to use Postman to send a GET request to the following route:

    {your workspace}--{your account}.myvtex.com/_v/app/analytics/realTime

    and it's expected that it replies with the data and status 200.

Attention! Generally, the account where you're running the app is appliancetheme.

image

Services in VTEX IO

Services in VTEX IO

Introduction

The VTEX IO platform allows developers to create unique commerce experiences using Web technologies. It’s possible to create frontend blocks for Store Framework, backend services exposing REST or GraphQL APIs, and combine a series of VTEX modules into a complete solution, packaging it into an app.

As VTEX IO powers big e-commerce operations, they require running code on a server. Services are how we run Node.js or .NET code on VTEX IO infrastructure, backed by API abstractions to improve developer experience.

Setting up our test bot

It's important for you to have our test bot installed in this course repository. With it installed, we can see your progress, even though it does not contain any tests or evaluations on each step (as in other courses we offer). To install it, follow the steps below:

  1. Open our test bot installation page and click on Configure;

  2. Select the Only selected repositories option, then click on Select repositories and type in service-course;

  3. Click on santosluiz000/service-course and then on Install.

    Note: The image above shows the process for store-block, but the steps for service-course are the same.

Services

A Service must be exported from a VTEX IO app, just like themes or store blocks, using builders node or dotnet. With these, you are able to develop a REST API without having to set up a server, GraphQL APIs and routes.

Services in VTEX IO support one-command rollbacks and continuous integration. They can export internal and external routes and run on top of Kubernetes. You can count on VTEX IO to manage the scalability of your services.

Inside the /node folder of a service lives service.json, where it´s possible to declare routes that the service must respond to and other configurations like timeout and memory.

During this course, you will implement some services in VTEX IO and learn a bit more about the possibilities that they offer to your development.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.