# Effects

## **Hello, world!**

**Effect** is the main building block of the whole framework. It is just a function which returns a stream of events. Using its generic interface we can define API endpoints, [middlewares](https://marblejs.gitbook.io/docs/v2/overview/middlewares), [error handlers](https://marblejs.gitbook.io/docs/v2/overview/error-handling) and much more (see next chapters). Let's define our first "hello world" `HttpEffect`!

```typescript
const helloEffect$: HttpEffect = req$ => req$.pipe(
  mapTo({ body: 'Hello, world!' }),
);
```

The *Effect* above responds to incoming request with `Hello, world!` message. In Marble.js, every *Effect* tries to be referentailly transparent, which means that each incoming request has to be mapped to an object with attributes like `body`, `status` or `headers`. If the *status* code or *headers* are not defined, then the API by default responds with *200* status and *application/json* header.

In order to route our first *Effect,* we have to define the path and HTTP method that the incoming request should be matched to. The simplest implementation of an HTTP API endpoint can look like this.

{% tabs %}
{% tab title="effect-with-pipe.ts" %}

```typescript
const hello$ = r.pipe(
  r.matchPath('/'),
  r.matchType('GET'),
  r.useEffect(helloEffect$));
```

{% endtab %}

{% tab title="effect-with-EffectFactory.ts" %}

```typescript
const hello$ = EffectFactory
  .matchPath('/')
  .matchType('GET')
  .use(req$ => req$.pipe(
    mapTo({ body: `Hello, world!` })
  ));
```

{% endtab %}
{% endtabs %}

Lets define a little bit more complex endpoint.

{% tabs %}
{% tab title="postUser.effect.1.ts" %}

```typescript
const postUser$ = r.pipe(
  r.matchPath('/user'),
  r.matchType('POST'),
  r.useEffect(req$ => req$.pipe(
    map(req => req.body as User),
    mergeMap(Dao.postUser),
    map(response => ({ body: response }))
  )));
```

{% endtab %}

{% tab title="postUser.effect.2.ts" %}

```typescript
const postUser$ = EffectFactory
  .matchPath('/user')
  .matchType('POST')
  .use(req$ => req$.pipe(
    map(req => req.body),
    mergeMap(Dao.postUser),
    map(response => ({ body: response }))
  );
```

{% endtab %}
{% endtabs %}

The example above will match every *POST* request that matches to `/user` url. Using previously parsed *POST* body (see [bodyParser$](https://marblejs.gitbook.io/docs/v2/api-reference/middleware-body) middleware) we can map it to example *DAO* which returns a `HttpEffectResponse` object as an action confirmation.

{% hint style="info" %}
Since Marble.js 2.0, you can build HTTP API routes using [`EffectFactory`](https://marblejs.gitbook.io/docs/v2/api-reference/core/core-effectfactory) builder or using new, pipeable functions inside[`r.pipe`](https://marblejs.gitbook.io/docs/v2/api-reference/core/r.pipe) function.
{% endhint %}

## HttpRequest

Every *HttpEffect* has an access to two most basics objects created by *http.Server*. **HttpRequest** is an abstraction over the basic *Node.js* [http.IncomingMessage](https://nodejs.org/dist/latest-v10.x/docs/api/http.html#http_class_http_incomingmessage) object. It may be used to access response status, headers and data, but in most scenarios you don't have to deal with all available APIs offered by *IncomingMessage* class. The most common properties available in request object are:

* *url*
* *method*
* *headers*
* *body (see* [*bodyParser$*](https://marblejs.gitbook.io/docs/v2/api-reference/middleware-body) *section)*
* *params (see* [*routing*](https://marblejs.gitbook.io/docs/v2/overview/routing) *chapter)*
* *query (see* [*routing*](https://marblejs.gitbook.io/docs/v2/overview/routing) *chapter)*

{% hint style="info" %}
For more details about available API offered in `http.IncomingMessage`, please visit [official Node.js docummentation](https://nodejs.org/dist/latest-v10.x/docs/api/http.html#http_class_http_incomingmessage).
{% endhint %}

## HttpResponse

Like the previously described *HttpRequest*, the **HttpResponse** object is also an abstraction over basic *Node.js* [http.ServerResponse](https://nodejs.org/dist/latest-v10.x/docs/api/http.html#http_class_http_serverresponse) object. Besides the default API, the response object exposes an `res.send` method, which can be a handy wrapper over *Marble.js* responding mechanism. For more information about the *res.send* method, visit [Middlewares](https://marblejs.gitbook.io/docs/v2/middlewares#sending-a-response-earlier) chapter.

{% hint style="info" %}
For more details about the available API offered in `http.ServerResponse`, please visit [official Node.js docummentation](https://nodejs.org/dist/latest-v10.x/docs/api/http.html#http_class_http_serverresponse).
{% endhint %}
