diff --git a/.eslintignore b/.eslintignore
index 9c30e8e44376c66e72229082fd69fd971524aa06..465054d8cb71842d55437e2fbdab15b12b3e0558 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -4,4 +4,5 @@
 
 # Auto generated by React
 serviceWorker.*
-setupTests.*
\ No newline at end of file
+setupTests.*
+setupProxy.*
\ No newline at end of file
diff --git a/.eslintrc.js b/.eslintrc.js
index 5803798cdc303788a1ef350c8a4e9e93ad79fd18..f1281fe4ed12edeaf22626d69001e31d8a896500 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -14,7 +14,8 @@ module.exports = {
 
   rules: {
     'react/prop-types': 0,
-    '@typescript-eslint/explicit-function-return-type': 2,
+    '@typescript-eslint/explicit-function-return-type': 1,
     'object-curly-newline': 0,
+    'implicit-arrow-linebreak': 0,
   },
 };
diff --git a/package-lock.json b/package-lock.json
index fa2b8b6f56e084cbc2819d3c6385790ab2b843cc..1809a4e2106aef7b676b8dd119da39e14f77a134 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2940,6 +2940,14 @@
         "hoist-non-react-statics": "^3.3.0"
       }
     },
+    "@types/http-proxy": {
+      "version": "1.17.4",
+      "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.4.tgz",
+      "integrity": "sha512-IrSHl2u6AWXduUaDLqYpt45tLVCtYv7o4Z0s1KghBCDgIIS9oW5K1H8mZG/A2CfeLdEa7rTd1ACOiHBc1EMT2Q==",
+      "requires": {
+        "@types/node": "*"
+      }
+    },
     "@types/istanbul-lib-coverage": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz",
@@ -8563,14 +8571,55 @@
       }
     },
     "http-proxy-middleware": {
-      "version": "0.19.1",
-      "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz",
-      "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==",
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.0.5.tgz",
+      "integrity": "sha512-CKzML7u4RdGob8wuKI//H8Ein6wNTEQR7yjVEzPbhBLGdOfkfvgTnp2HLnniKBDP9QW4eG10/724iTWLBeER3g==",
       "requires": {
-        "http-proxy": "^1.17.0",
-        "is-glob": "^4.0.0",
-        "lodash": "^4.17.11",
-        "micromatch": "^3.1.10"
+        "@types/http-proxy": "^1.17.4",
+        "http-proxy": "^1.18.1",
+        "is-glob": "^4.0.1",
+        "lodash": "^4.17.19",
+        "micromatch": "^4.0.2"
+      },
+      "dependencies": {
+        "braces": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+          "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+          "requires": {
+            "fill-range": "^7.0.1"
+          }
+        },
+        "fill-range": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+          "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+          "requires": {
+            "to-regex-range": "^5.0.1"
+          }
+        },
+        "is-number": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+          "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
+        },
+        "micromatch": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+          "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+          "requires": {
+            "braces": "^3.0.1",
+            "picomatch": "^2.0.5"
+          }
+        },
+        "to-regex-range": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+          "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+          "requires": {
+            "is-number": "^7.0.0"
+          }
+        }
       }
     },
     "http-signature": {
@@ -16914,6 +16963,17 @@
             }
           }
         },
+        "http-proxy-middleware": {
+          "version": "0.19.1",
+          "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz",
+          "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==",
+          "requires": {
+            "http-proxy": "^1.17.0",
+            "is-glob": "^4.0.0",
+            "lodash": "^4.17.11",
+            "micromatch": "^3.1.10"
+          }
+        },
         "is-absolute-url": {
           "version": "3.0.3",
           "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz",
diff --git a/package.json b/package.json
index a6c602e19f26c11f88c4f3a168be097b576d9f4c..337d77d817d78cf3920f2b1503b53dbf8d31c583 100644
--- a/package.json
+++ b/package.json
@@ -47,6 +47,7 @@
   "dependencies": {
     "@material-ui/core": "^4.11.0",
     "axios": "^0.20.0",
+    "http-proxy-middleware": "^1.0.5",
     "react": "^16.13.1",
     "react-dom": "^16.13.1",
     "react-hook-form": "^6.5.3",
diff --git a/src/core/App.tsx b/src/core/App.tsx
index ebed2efd7cd3c9fe7e9dc87e9c9f96982eac1d14..f9243ddba1c4f5508331442f87cb184322ba0c32 100644
--- a/src/core/App.tsx
+++ b/src/core/App.tsx
@@ -1,6 +1,7 @@
-import React from 'react';
+import React, { useEffect } from 'react';
 import { BrowserRouter as Router } from 'react-router-dom';
 import styled from 'styled-components';
+import useAddNews from '../hooks/useAddNews';
 import Footer from './components/Footer';
 import Header from './components/Header';
 import MainRouting from './components/MainRouting';
@@ -16,7 +17,19 @@ const MainContent = styled.div`
   height: 100%;
 `;
 
-function App() {
+function App(): React.ReactElement {
+  const [response, addNews] = useAddNews();
+
+  useEffect(() => {
+    addNews({ body: { title: 'Testing', text: 'Test Test TEST' } });
+  }, [addNews]);
+
+  useEffect(() => {
+    if (response.data) {
+      console.log(response.data.text);
+    }
+  }, [response.data]);
+
   return (
     <Router>
       <Container>
diff --git a/src/hooks/types.ts b/src/hooks/types.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d639a344b70e94866b43d4923f40304dcbb6421c
--- /dev/null
+++ b/src/hooks/types.ts
@@ -0,0 +1,29 @@
+import { AxiosPromise } from 'axios';
+
+export interface ResponseData<T> {
+  isLoading: boolean;
+  isError: boolean;
+  data?: T;
+}
+
+export interface RequestArgs<T = any> {
+  request: ApiRequest<T>;
+  initialData?: T;
+  initialParams?: RequestParams;
+}
+
+export interface RequestParams {
+  body?: any;
+  params?: any;
+  args?: any;
+}
+
+export type ApiRequest<T> = (params: RequestParams) => AxiosPromise<T>;
+
+export type Refetch = (params?: RequestParams) => void;
+
+export interface INews {
+  title: string;
+  text: string;
+  publishedAt: string;
+}
diff --git a/src/hooks/useAddNews.ts b/src/hooks/useAddNews.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0afeea1a19ca924ff4bee70407b2c9e92f41a9ff
--- /dev/null
+++ b/src/hooks/useAddNews.ts
@@ -0,0 +1,12 @@
+import { INews } from './types';
+import useRequest from './useRequest';
+import userRestQueries from './useRestQueries';
+
+const useAddNews = () => {
+  const { post } = userRestQueries();
+  const request = post<INews>('/api/v1/news');
+
+  return useRequest<INews>({ request });
+};
+
+export default useAddNews;
diff --git a/src/hooks/useGetNewsList.ts b/src/hooks/useGetNewsList.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2cca43ad421fba11731dd1aad220f0ac83dd0af2
--- /dev/null
+++ b/src/hooks/useGetNewsList.ts
@@ -0,0 +1,12 @@
+import { INews } from './types';
+import useRequest from './useRequest';
+import userRestQueries from './useRestQueries';
+
+const useGetNewsList = (data?: INews[]) => {
+  const { get } = userRestQueries();
+  const request = get<INews[]>('/api/v1/news');
+
+  return useRequest<INews[]>({ request, initialData: data });
+};
+
+export default useGetNewsList;
diff --git a/src/hooks/useRequest.ts b/src/hooks/useRequest.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6e41e58f6add946cf3015c953537ab50a9879353
--- /dev/null
+++ b/src/hooks/useRequest.ts
@@ -0,0 +1,40 @@
+import { useCallback, useEffect, useState } from 'react';
+import { Refetch, RequestArgs, ResponseData } from './types';
+
+function useRequest<T = any>({ request, initialData }: RequestArgs<T>): [ResponseData<T>, Refetch] {
+  const [data, setData] = useState(initialData);
+  const [isLoading, setIsLoading] = useState(false);
+  const [isError, setIsError] = useState(false);
+  const [fetching, setFetching] = useState(false);
+  const [requestParams, setRequestParams] = useState({});
+
+  const refetch = useCallback((newParams?) => {
+    setRequestParams(newParams ?? {});
+    setFetching(true);
+  }, []);
+
+  useEffect(() => {
+    const fetchData = async () => {
+      setIsError(false);
+      setIsLoading(true);
+
+      try {
+        const result = await request(requestParams);
+
+        setData(result.data);
+      } catch (error) {
+        setIsError(true);
+      }
+      setFetching(false);
+      setIsLoading(false);
+    };
+
+    if (fetching && !isLoading) {
+      fetchData();
+    }
+  }, [request, fetching, isLoading, requestParams]);
+
+  return [{ data, isLoading, isError }, refetch];
+}
+
+export default useRequest;
diff --git a/src/hooks/useRestQueries.ts b/src/hooks/useRestQueries.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1201e5c74ff6438a529af36d11dd6d789719be31
--- /dev/null
+++ b/src/hooks/useRestQueries.ts
@@ -0,0 +1,20 @@
+import axios, { AxiosRequestConfig } from 'axios';
+import { ApiRequest, RequestParams } from './types';
+
+function userRestQueries(
+  // When a request needs more config like CancelToken, etc.
+  config?: AxiosRequestConfig,
+): Record<string, <Data>(path: string) => ApiRequest<Data>> {
+  return {
+    get: <Data>(path: string) => (params: RequestParams) =>
+      axios.get<Data>(path, { ...config, ...params }),
+    post: <Data>(path: string) => (params: RequestParams) =>
+      axios.post<Data>(path, params.body ?? {}, { ...config, ...params }),
+    put: <Data>(path: string) => (params: RequestParams) =>
+      axios.put<Data>(path, params.body ?? {}, { ...config, ...params }),
+    delete: (path: string) => (params: RequestParams) =>
+      axios.delete(path, { ...config, ...params }),
+  };
+}
+
+export default userRestQueries;
diff --git a/src/setupProxy.js b/src/setupProxy.js
new file mode 100644
index 0000000000000000000000000000000000000000..a4b1c75f070cdcf2248b8bdef529c9b826bc4cb3
--- /dev/null
+++ b/src/setupProxy.js
@@ -0,0 +1,11 @@
+const { createProxyMiddleware } = require('http-proxy-middleware');
+
+module.exports = function (app) {
+  app.use(
+    '/api/v1',
+    createProxyMiddleware({
+      target: 'http://localhost:8000',
+      changeOrigin: true,
+    }),
+  );
+};