Hi, my name is
Martin Sagat
I build things for the web.
I'm a Senior Software Engineer specializing in building scalable web and mobile applications. With expertise in cloud technologies and modern web frameworks, I create efficient, maintainable solutions that drive business growth.

About Me
I'm a Senior Software Engineer specializing in scalable web and mobile applications. I blend cloud and modern web expertise with AI-powered engineering workflows to ship efficient, maintainable systems faster without sacrificing quality. I'm also passionate about crafting clean, intuitive UI/UX that elevates every product I work on.
Where I've Worked







Noteworthy Projects

Stepflow
Stepflow helps people transform their fitness journey with personalized exercise guidance, yoga routines, and workout plans tailored to their goals.
Due to rights and confidentiality agreements, certain commercial projects are not featured.
Latest Articles
Service layer in frontend application
When working on a code base that scales up, one can easily get overwhelmed by the complexity of code if not implemented properly.
One of the ways that can help to prevent confusions and keep things in place for the long run is to establish a service layer. Service layer
is an additional layer between the backend and other components which consume data from our endpoints.
Let's have a look how this can be easily implemented in Nuxt (Framework that generates Vue.js application).
Implementation Example
There is a requirement to create a page that will display a list of employees. We will receive the data from an API endpoint:
[
{
"name": "James Smith",
"age": 32,
"role": "Accountant"
},
{
"name": "Samantha Robberts",
"age": 28,
"role": "Product Owner"
}
// ...
]
Firstly, we need to create custom types based on the endpoint response:
export interface Employee {
name: string;
age: number;
role: string;
}
import { Employee } from '~/types/employee'
export interface EmployeesResponse {
data: Employee[];
}
```paragraph
For our application to consume the endpoint, we will create a service called "employees" with a method called list(), this method will return a promise with our employees (or error if the backend does not return expected result):
```js{1,3-5}[services/employees.ts]
import type { NuxtAxiosInstance } from '@nuxtjs/axios'
import type { Context, NuxtError } from '@nuxt/types'
import type { EmployeeResponse } from '~/types/apiResponses/employees'
import type { Employee } from '~/types/employee'
export default class Employees {
axios: NuxtAxiosInstance
error: Context['error']
constructor(axios: NuxtAxiosInstance, error: Context['error']) {
this.axios = axios
this.error = error
}
async list(): Promise<Employees[] | undefined> {
try {
const response: any = await this.axios.get('employees')
const employees: Employee[] = response.data
return employees
}
catch (e: any) {
this.error({
message: e.response.message,
path: '/error',
statusCode: e.response.status,
} as NuxtError)
}
}
}
paragraph
Next we are required to inject the service into Nuxt as plugin:
import { Plugin } from '@nuxt/types'
import Employees from '~/services/employees'
const employees: Plugin = (context, inject) => {
inject('employees', new Employees(context.$axios, context.error))
}
export default employees
Now we extend the Vue type with the new service we created:
import Vue from 'vue'
import Employees from "~/services/employees";
declare module 'vue/types/vue' {
interface Vue {
$employees: Employees,
}
}
Dont forget to include this file in tsconfig:
{
"files": [
"types/vue.d.ts",
]
}
We can now call the employees service directly from anywhere within our application. On response success, we can set the received data into our store:
created() {
this.$employees.list().then( async (employees) => {
await this.$store.dispatch('employees/set', employees)
})
}
Congratulations, you have implemented your first service inside yout Nuxt application. You can learn more about store and how to manage application state using VueX and Typescript in next article.
Using VueX and TypeScript in Nuxt
VueX is a state management library. It holds data in centralised place which can be used from anywhere within the application. To learn more about VueX, you can visit the original documentation where the concept is explained in detail.
In my previous article. I have explained how we can create a service layer within our Nuxt application. Now let's take a look how we can store the returned values from our endpoints into the store.
Firstly, make sure you have created types for data you wish to store:
export interface Employee {
name: string;
age: number;
role: string;
}
We also require to create store index module. This module can have state with an empty object, but it is required for implementing other modules such the one we create (employees).
export interface RootState {}
export const state = (): RootState => ({})
Now we are ready to create module employees:
import Vue from 'vue'
import { Employee } from '~/types/employee'
import { RootState } from '~/store/index'
import { GetterTree, ActionTree, MutationTree } from 'vuex'
export interface EmployeeState {
employees: Employee[]
}
export const state = (): EmployeeState => ({
employees: [] as Employee[],
})
export const getters: GetterTree<EmployeeState, RootState> = {
get(state: EmployeeState): Employee[] {
return state.employees
},
}
export const MutationType = {
SELECT: 'select',
SET: 'set',
}
export const mutations: MutationTree<EmployeeState> = {
[MutationType.SET]: (state: EmployeeState, employees: Employee[]) => {
Vue.set(state, 'employees', employees)
},
}
export const actions: ActionTree<EmployeeState, RootState> = {
set({ commit }, employees: Employee[]) {
commit(MutationType.SET, employees)
}
}
Using the module from a component
Calling a service to fetch data and set returned value to employees modules store:
created() {
/* to see where the $employees is coming from
* read my article about sercices: https://martinsagat.com/articles/1
*/
this.$employees.list().then( async (employees) => {
await this.$store.dispatch('employees/set', employees)
})
}
Getting employees from the store to component:
computed: {
employees() {
return this.$store.getters['employees/get']
}
}
An example of computed property using getter and setter:
computed: {
employees: {
get(): Employees {
return this.$store.getters['employees/get']
},
set(employees: Employee[]) {
this.$store.dispatch('employees/set', employees)
}
}
}
Things I enjoy

Climbing
Love the challenge and rush of climbing. There's something satisfying about pushing past what you thought was possible.

Ice Hockey
Big fan of ice hockey. Love the fast pace and teamwork - win or lose, it's always better with a good group.

Chess
Love playing chess - it's a great way to unwind and keep my mind sharp. Always up for a game if you're interested!
Challenge me?
Get In Touch
I'm currently looking for new opportunities, my inbox is always open. Whether you have a question or just want to say hi, I'll try my best to get back to you!
Say Hello