<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: SamuelRafini</title>
    <description>The latest articles on DEV Community by SamuelRafini (@samuelrafini).</description>
    <link>https://dev.to/samuelrafini</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F212178%2F7dd5b7cf-911d-4efc-8a29-a07192979252.jpeg</url>
      <title>DEV Community: SamuelRafini</title>
      <link>https://dev.to/samuelrafini</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/samuelrafini"/>
    <language>en</language>
    <item>
      <title>How to Build a Clean Redux Architecture With Redux-Observable and Typescript</title>
      <dc:creator>SamuelRafini</dc:creator>
      <pubDate>Wed, 18 Nov 2020 07:56:49 +0000</pubDate>
      <link>https://dev.to/samuelrafini/how-to-build-a-clean-redux-architecture-with-redux-observable-and-typescript-15g9</link>
      <guid>https://dev.to/samuelrafini/how-to-build-a-clean-redux-architecture-with-redux-observable-and-typescript-15g9</guid>
      <description>&lt;h1&gt;
  
  
  How to Build a Clean Redux Architecture With Redux-Observable and Typescript
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Easily create completely typesafe actions with less boilerplate and completely typesafe Reducers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To be honest I used to hate Redux but my perspective changed quickly as soon as I had to work with large complicated codebases. Redux is amazing for that and once you have experience with such, you’ll appreciate it. In this article, I’m going to show you how I setup redux with redux-observables (also works with other middlewares like redux-saga ) and typesafe-actions to be clean and scalable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Folder structure
&lt;/h2&gt;

&lt;p&gt;The folder structure is pretty straightforward. Inside my src folder, I’ve added several folders:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;components&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;pages&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;utils&lt;/strong&gt; reusable fetch function and localstorage function&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;services&lt;/strong&gt; with an http folder for my requests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;redux&lt;/strong&gt; well for redux 😆, notice I’m using the ducks architecture&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Basically, in ducks architecture, you have a &lt;strong&gt;separate folder per domain or feature&lt;/strong&gt; containing actions, epics/sagas, reducers, and selectors files.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;On the official documentation of Redux they strongly recommend Structure Files as Feature Folders or Ducks&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;they strongly recommend Structure Files as Feature Folders or Ducks&lt;/p&gt;

&lt;p&gt;In this example, I will create a simple application where you can search for NBA players and sort by name. I’m receiving data from &lt;a href="https://www.balldontlie.io/"&gt;www.balldontlie.io&lt;/a&gt; API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/samuelrafini/test-app"&gt;Git Repo&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📁 test-app/
┣ 📁 public/
┣ 📁 src/
┃ ┣ 📁 components/
┃ ┣ 📁 pages/
┃ ┣ 📁 redux/
┃ ┃ ┣ 📁 player/
┃ ┃ ┃ ┣ 📄 actions.ts
┃ ┃ ┃ ┣ 📄 epics.ts
┃ ┃ ┃ ┣ 📄 reducers.ts
┃ ┃ ┃ ┗ 📄 selectors.ts
┃ ┃ ┣ 📄 rootAction.ts
┃ ┃ ┣ 📄 rootEpic.ts
┃ ┃ ┣ 📄 rootReducer.ts
┃ ┃ ┣ 📄 store.ts
┃ ┃ ┗ 📄 utils.ts
┃ ┣ 📁 services/
┃ ┃ ┗ 📁 http/
┃ ┃   ┗ 📄 nbaRequests.ts
┃ ┣ 📁 utils/
┃ ┃ ┣ 📄 fetchApi.ts
┃ ┃ ┗ 📄 localstorage.ts
┃ ┣ App.tsx
┃ ┣ 📄 index.tsx
┃ ┣ 📄 interfaces.ts
┃ ┣ 📄 react-app-env.d.ts
┣ 📄 package.json
┗ 📄 tsconfig.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Actions Setup
&lt;/h2&gt;

&lt;p&gt;We create a simple fetch player’s actions inside players. Players, in this case, is the domain/feature of this application.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createAction } from 'typesafe-actions';
import { FetchPlayersRequest, Player, PaginationMeta, ErrorResponse } from '../../interfaces';

export const getPlayers = createAction("GET_PLAYERS")&amp;lt;FetchPlayersRequest&amp;gt;();
export const getPlayersSuccess = createAction("GET_PLAYERS_SUCCESS")&amp;lt;{data: Player[]; meta: PaginationMeta}&amp;gt;();
export const getPlayersFailed = createAction("GET_PLAYERS_FAILED")&amp;lt;ErrorResponse&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Notice how createAction from Typesafe-actions helps us to reduce types verbosity. So basically getPlayersSuccess returns an action with an object of dataPlayer and meta as payload. for example&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const getName = createAction("GET_FULL_NAME")&amp;lt;{firstName: string; lastName: string}&amp;gt;();

getName({firstname: "Samuel", lastName: "Rafini"}); // {type: "GET_FULL_NAME", payload: {firstName: 'Samuel', lastName: 'Rafini'}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the root of the redux folder, we then add rootAction.ts file with the following, so we can join actions from other features/domains.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as playerActions from './player/actions';

export default {
    player: playerActions,
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Before going any further we can extend and add types of typesafe-actions like so&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { StateType, ActionType } from 'typesafe-actions';

/// &amp;lt;reference types="react-scripts" /&amp;gt;

declare module 'typesafe-actions' {
  export type Store = StateType&amp;lt;typeof import('./redux/store').default&amp;gt;;

  export type RootState = StateType&amp;lt;typeof import('./redux/rootReducer').default&amp;gt;;

  export type RootAction = ActionType&amp;lt;typeof import('./redux/rootAction').default&amp;gt;;

  interface Types {
    RootAction: RootAction;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Reducers Setup
&lt;/h2&gt;

&lt;p&gt;the Reducer is also straightforward. for our player state, we create a PlayerState interface and an initial state, then we use createRudecer from Typesafe-actions which helps us write our reducers without the switch case statement.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createReducer } from 'typesafe-actions';
import { Player, PaginationMeta, ErrorResponse } from '../../interfaces';

export interface PlayerState {
    players: Player[];
    pagination: PaginationMeta;
    loading: boolean;
    error?: ErrorResponse;
}

const initState: PlayerState = {
    players: [],
    pagination: {
      total_pages: 0,
      current_page: 1,
      next_page: 0,
      per_page: 100,
      total_count: 0,
    },
    loading: false,
    error: undefined,
}

const playerReducer = createReducer&amp;lt;PlayerState&amp;gt;(initState, {
    GET_PLAYERS: (state, _) =&amp;gt; ({...state, loading: true}),
    GET_PLAYERS_SUCCESS: (state, action) =&amp;gt; ({...state, loading: false, players: action.payload.data, pagination: action.payload.meta}),
    GET_PLAYERS_FAILED: (state, action) =&amp;gt; ({...state, loading: false, error: action.payload}),
});

export default playerReducer;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Just like the actions we have a rootReducer file where we combine all our reducers&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { combineReducers } from 'redux';
import playerReducer from './player/reducers';

export default combineReducers({
    player: playerReducer,
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Middleware Setup (Redux-Observables)
&lt;/h2&gt;

&lt;p&gt;I will not go in details on Redux-observables but its worth noticing the isActionOf function from typeSafe-actions &lt;strong&gt;filter(isActionOf(getPlayers))&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { combineEpics, Epic } from 'redux-observable';
import { filter, mergeMap, debounceTime } from 'rxjs/operators';

import { isActionOf, RootAction, RootState } from 'typesafe-actions';
import { getPlayers, getPlayersSuccess, getPlayersFailed } from './actions';
import { fetchPlayers, fetchSeasonAverages } from '../../services/http/nbaRequests';
import { Player, SeasonAverages } from '../../interfaces';

export const getPlayersEpic: Epic&amp;lt;RootAction, RootAction, RootState&amp;gt; = (action$, state$) =&amp;gt; {
    return action$.pipe(
        debounceTime(500),
        filter(isActionOf(getPlayers)),
        mergeMap(async ({payload}) =&amp;gt; {
            const response = await fetchPlayers({search: payload.search, page: payload.page, perPage: payload.perPage});
            if (response.data) {
              const playersIds = response.data.map((player: Player) =&amp;gt; player.id);
              const playersAvg = await fetchSeasonAverages(playersIds);

              const findAvg = (id: number) =&amp;gt; playersAvg.data.find((item: SeasonAverages) =&amp;gt; item.player_id === id);

              const players: Player[] = response.data.map((player: Player) =&amp;gt; ({...player, seasonAverage: findAvg(player.id)}))
              return getPlayersSuccess({data: players, meta: response.meta})
            }
            return getPlayersFailed(response);
        }),
    )
};

export const playerEpics = combineEpics(
  getPlayersEpic
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Yep, you’ve guessed it! RootEpics! 😆&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { combineEpics } from 'redux-observable';&lt;br&gt;
import { playerEpics } from './player/epics';

&lt;p&gt;export default combineEpics(&lt;br&gt;
  playerEpics,&lt;br&gt;
);&lt;br&gt;
&lt;/p&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Store Setup&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;Last but not least you can set up the store as following nothing new actually.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createStore, applyMiddleware } from 'redux';&lt;br&gt;
import { RootAction, RootState } from 'typesafe-actions';&lt;br&gt;
import { createEpicMiddleware } from 'redux-observable';

&lt;p&gt;import rootReducer from './rootReducer';&lt;br&gt;
import rootEpic from './rootEpic';&lt;br&gt;
import { composeEnhancers } from './utils';&lt;br&gt;
import { loadState, saveState } from '../utils/localstorage';&lt;/p&gt;

&lt;p&gt;export const epicMiddleware = createEpicMiddleware&amp;lt;&lt;br&gt;
    RootAction,&lt;br&gt;
    RootAction,&lt;br&gt;
    RootState&lt;br&gt;
&amp;gt;();&lt;/p&gt;

&lt;p&gt;const middlewares = [epicMiddleware];&lt;/p&gt;

&lt;p&gt;const enhancer = composeEnhancers(applyMiddleware(...middlewares));&lt;/p&gt;

&lt;p&gt;const initialState = loadState();&lt;/p&gt;

&lt;p&gt;const store = createStore(rootReducer, initialState, enhancer);&lt;/p&gt;

&lt;p&gt;store.subscribe(() =&amp;gt; {&lt;br&gt;
  saveState(store.getState());&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;epicMiddleware.run(rootEpic);&lt;/p&gt;

&lt;p&gt;export default store;&lt;br&gt;
&lt;/p&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Alternative ways&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;If you still find setting up the store requires too much boilerplate or complicated you can use redux-toolkit which also is highly recommended in the &lt;a href="https://redux.js.org/style-guide/style-guide"&gt;official documentation of Redux&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It is intended to be the standard way to write Redux logic. I never used it myself yet, but will use it in my next project.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How To Approach Go (Golang)</title>
      <dc:creator>SamuelRafini</dc:creator>
      <pubDate>Thu, 19 Dec 2019 15:27:17 +0000</pubDate>
      <link>https://dev.to/samuelrafini/just-give-it-a-go-golang-3mm2</link>
      <guid>https://dev.to/samuelrafini/just-give-it-a-go-golang-3mm2</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1200%2F1%2ApFaeNO48gYlRMQii977cQg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1200%2F1%2ApFaeNO48gYlRMQii977cQg.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There is a huge hype around Golang and the popularity is growing. So why not give it a “Go”.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But all joking aside, Go was invented by &lt;a href="https://de.wikipedia.org/wiki/Robert_Griesemer" rel="noopener noreferrer"&gt;Robert Griesemer&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Rob_Pike" rel="noopener noreferrer"&gt;Rob Pike&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Ken_Thompson" rel="noopener noreferrer"&gt;Ken Thompson&lt;/a&gt; and few other engineers at Google. In other words, &lt;strong&gt;Go was created by geniuses.&lt;/strong&gt; Big companies such as Youtube, Twitter, Kubernetes, Docker, and Uber are using Go. Furthermore, Ryan Dahl, the creator of Node.js gave up his creation and promoted Go. Read more → &lt;a href="https://mappingthejourney.com/single-post/2017/08/31/episode-8-interview-with-ryan-dahl-creator-of-nodejs/" rel="noopener noreferrer"&gt;Ryan Dahl&lt;br&gt;
interview&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Most people say Go is easy to learn
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;I have some experience programming in Java and javascript and I find it&lt;br&gt;
indeed very easy to learn, well the basics 😅. Once you go through the tour of go &lt;a href="https://tour.golang.org/basics/1" rel="noopener noreferrer"&gt;https://tour.golang.org/basics/1&lt;/a&gt; you will understand the majority of things in Go.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/KbYSfnjloMwgXRjskg/source.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/KbYSfnjloMwgXRjskg/source.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, when it comes to &lt;strong&gt;design and architect your go code&lt;/strong&gt; it’s a&lt;br&gt;
bit challenging in the beginning.&lt;br&gt;&lt;br&gt; &lt;strong&gt;Organize your code is very important,&lt;/strong&gt; especially when you want to change some logic of your code then the well-structured project can easily adopt the changes. An old and popular style is Object-Oriented programming. Most popular programming languages like Java, C++, C# uses object-oriented programming.&lt;/p&gt;

&lt;p&gt;In Go… well, 😑 &lt;strong&gt;Go is not considered an object-oriented language&lt;/strong&gt; for some, because it does not have classes, no inheritance, and interfaces work differently blah blah blah…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/lmjyMh4ZwDpspGsFIQ/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/lmjyMh4ZwDpspGsFIQ/giphy.gif" alt="alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  But 🤷🏾‍♂️
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;“Go is a profoundly object oriented language.” — Rob Pike&lt;br&gt;
(&lt;a href="https://youtu.be/rKnDgT73v8s?t=750" rel="noopener noreferrer"&gt;https://youtu.be/rKnDgT73v8s?t=750&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;





&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Structs&lt;/strong&gt; instead of classes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Different approach to inheritance&lt;/strong&gt;: &lt;em&gt;Composition over inheritance&lt;/em&gt; 
&lt;a href="https://medium.com/humans-create-software/composition-over-inheritance-cb6f88070205" rel="noopener noreferrer"&gt;Inheritance is when you design your types around what they are, and
composition is when you design types around what they
do-&lt;/a&gt;*
→ Fun Fun Functions&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Go interfaces are very different&lt;/strong&gt;: interfaces are satisfied &lt;strong&gt;implicitly&lt;/strong&gt;.&lt;br&gt;this can be confusing at first. Type satisfies Interface without&lt;br&gt;
implementing it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;→ → → Will write more about the topics mentioned above in the future* 🤗&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;So it’s safe to say that you could implement object-oriented behavior in Go *(still doesn’t make it object-oriented language)&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What I’m trying to say
&lt;/h3&gt;

&lt;p&gt;Just write Go like you’re writing Go. &lt;strong&gt;Don’t treat it like other languages&lt;/strong&gt;.&lt;br&gt;
It &lt;strong&gt;shifts our mindset&lt;/strong&gt; about the usual flow of application development. With&lt;br&gt;
Golang, you tend to think more about microservices than your old school Java monolithic projects. I love Java btw 🤫.&lt;/p&gt;

&lt;p&gt;Uber, for example, has moved to &lt;a href="http://en.wikipedia.org/wiki/Service-oriented_architecture" rel="noopener noreferrer"&gt;service-oriented architecture&lt;/a&gt; (SOA)&lt;br&gt;
they adopted a &lt;strong&gt;microservice architecture&lt;/strong&gt; a design pattern where they can build independently deployable services. → &lt;a href="https://eng.uber.com/service-oriented-architecture/" rel="noopener noreferrer"&gt;https://eng.uber.com/service-oriented-architecture/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another good read on how *&lt;em&gt;Uber built their highest query per second service using Go *&lt;/em&gt; → &lt;a href="https://eng.uber.com/go-geofence/" rel="noopener noreferrer"&gt;https://eng.uber.com/go-geofence/&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Thank you for reading!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Please don’t hesitate to share any feedback.&lt;/p&gt;

</description>
      <category>go</category>
      <category>architecture</category>
      <category>microservices</category>
      <category>oop</category>
    </item>
  </channel>
</rss>
