DEV Community

Cover image for Developing and Publishing a Typescript-based SDK
James Oyanna
James Oyanna

Posted on • Edited on

Developing and Publishing a Typescript-based SDK

A Software Development Kit (SDK) is a set of development tools, libraries, documentation, and sample code that allows developers to create applications for a specific platform or system.

SDKs are used to make it easier and faster for developers to build applications that interact with a particular system, by providing pre-built components and APIs that abstract away the complexity of the system.

Say you want to interact with 3rd party APIs, if there was no SDK, you would have to write the HTTP client, manage authentication, do the error handling, and so on.

Having an SDK provides a better developer experience and it allows the developers to use your APIs in the right way.

TypeScript has gained popularity as a preferred language for building SDKs due to its strong typing and maintainability features.

In this article, we will discuss how to develop a simple SDK with TypeScript. This SDK will connect to the JSON Placeholder API for fetching posts, creating and retrieving a particular post from the API. We will then also publish it on the npm registry.

The full code implementation can be found on this repo

Setting up our development environment:

The first step is to set up the development environment. This involves installing Node.js and TypeScript on your computer, as well as any other dependencies that you might need.

Create a folder in your computer and name it typescript-sdk
Navigate into the folder and open your command line in it.

Create a new folder inside the typescript-sdk folder, call it sdk. Navigate into it from the command line by typing cd sdk.

Inside the sdk folder, initialize a new project using the command npm init -y.
A package.json file will automatically be created on it for you.

Now let install the dependencies we will be needing for this project using this commands:

npm install microbundle

npm install typescript@latest -g

npm install isomorphic-unfetch

Microbundle- Microbundle is a tool used for bundling JavaScript code into a single, self-contained file that can be used in web applications or other software projects.

It is particularly useful for developing libraries or modules that need to be distributed in a standalone format.

Now, lets add the necessary details to our package.json file.
Open the package.json file and update the following

Change "main": "index.js", to "main": "dist/index.js",.

In the script section, add this script:
"build": "rm -rf dist && microbundle --tsconfig tsconfig.json --no-sourcemap",

Now create a tsconfig.json file - You can either create it manually or by running this command:
tsc --init

Remove the default configuration in the tsconfig.json file and add the one below:




{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "allowSyntheticDefaultImports": true,
    "target": "es2017",
    "sourceMap": false,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "test", "lib", "**/*spec.ts"]
}


Enter fullscreen mode Exit fullscreen mode

In your project folder create a new folder and name it src. Create two files - index.ts and base.ts inside the src folder.

Inside the base.ts file add the following code:

Here in this code, we define a Base class which is to be used as a base class for other classes that need to make API requests.

The class has two private properties, apiKey and baseUrl, and a constructor that takes a configuration object containing an API key and an optional base URL.

This Base class also has a protected method called request that makes an HTTP request to the API. The method takes an endpoint path and an optional RequestInit object, which can be used to pass additional options to the fetch function.

Inside the request method, the base URL and API key are used to construct the full URL for the API endpoint.

A headers object is also created, which includes the API key and sets the content type to JSON.

The Object.assign method is then used to merge the options parameter with the headers object, creating a new config object that can be passed to the fetch function.

The fetch function is then called with the full URL and the config object, and the response is stored in the response variable.

If the response is OK (i.e. the status code is in the 200-299 range), the JSON response data is extracted using the response.json() method and returned as the requested type T.

If the response is not OK, an error is thrown with the response status text as the error message.

Now lets implement our post methods.

Inside your src folder, create another folder called posts and inside the posts folder you just created, add 2 files - index.ts and types.ts.
Open the types.ts file and add the following code:

Here in this code,we define two TypeScript types, Post and NewPost.
The Post type is an object with four properties: id, title, body, and userId. Each property has a specific type: id is a number, title and body are strings, and userId is also a number.

The NewPost type is defined using TypeScript's Omit utility type, which takes an existing type and creates a new type by omitting one or more specified properties.

In this case, we're using Omit to create a new type that's similar to Post, but with the id property omitted.
This is useful in situations where we need to create a new object that's similar to an existing object, but with some changes.

Now, in the index.ts inside the posts folder, add the following code:

Here in the code, we implemented the Posts API and we are using Typescript to define the types of the API responses and requests.

The Posts class extends the Base class and implements the methods of the Posts API.
We added a getPostById method that takes an ID and returns a single post with that ID.

We also added a getPosts method which returns an array of all posts.
Then we added createPost method that creates a new post by sending a POST request with the new post data as the request body.
The API responses and requests are defined using the Post and NewPost types respectively.

We define constant resourceName which is used as the resource name for the Posts API.

Each method sends a request to the API using the request() method inherited from the Base class, passing the appropriate URL and options.
The methods return promises that resolve to the response data, which is typed according to the method's return type definition.

Now lets add mixins- Mixins are a programming concept that allows classes to inherit properties and methods from multiple sources.

In other words, mixins enable the creation of a new class by combining functionality from multiple classes without having to use inheritance.

In your src folder, create a file called utils.ts and add the following code:

Here in this code we define a function called applyMixins which is used to apply properties and methods of multiple base classes to a single derived class.

The function takes two parameters, derivedCtor which represents the derived class and baseCtors which is an array of base classes.

Inside the function, we use the forEach method to iterate over each base class in the baseCtorsarray.

We then use the getOwnPropertyNames method to get all the property names of the prototype object of the base class.

Then, for each property, the defineProperty method is used to define a new property on the prototype object of the derived class.
This new property has the same name and property descriptor as the corresponding property on the base class.

Next, we will create a index.ts file in our src folder and the following code:

Here in this code, we define and exports the Typicode class as the default export of the module.
The Typicode class extends the Base class and implements the Posts class.

The Posts class provides methods to interact with the Posts API. The applyMixins function is used to add the methods and properties of the Posts class to the Typicode class.

This is done using the interface keyword to declare that Typicode implements Posts and then calling applyMixins with Typicode and an array containing Posts. This allows Typicode to inherit the functionality of the Posts class and extend the functionality of the Base class.

Now before we publish our sdk to npm registry, lets make some changes to our package.json file.
Here is how it should look like after the update.

Now run npm run build to build our sdk. This would generate a dist file.

Now, let's publish our sdk.
You will have to create an account on the NPM website if you haven't already done so.

Log in to your NPM account from the command line in your project directory by running npm login and providing your credentials.

You can test your package locally using the npm link command to create a symbolic link from your package to your local node_modules directory.

We won't be doing any local testing here since everything appears to be functioning correctly.

Run the command npm init --scope=oyanna
Ensure you replace the scope value i.e oyanna with your name or any name you like before running the command.

Use the npm publish --access-public command to publish your package to the NPM registry.
If your publishing works fine, you should see this on your npm account:

npm-package

How to use the SDK:

To use this SDK,create a folder called sdk-test
Inside the folder, initialize a new project by running npm init -y in the directory or folder you have just created. This would generate a pakage.json file in it.

Create a tsconfig.json file inside the folder and add the following code:

Install the SDK package we have published by running the command:
npm install @oyanna/typescript-sdk

Create a new folder inside your project directory and add a new file called run.ts
Add the following code the the file:

Here, we imported the Typicode class from our SK.

We then created a new instance of the Typicode is with an object that contains an API key as the property. We assigned this instance to a variable called client.

To make use of the API to get post from the jsonplaceholder api, we called the getPosts method on the client object, which retrieves a list of posts from the Typicode API.

The result is a Promise which, when resolved, and logs the retrieved posts to the console.

To run the project and see the result in the console, add the following script to your package.json file.

"scripts": {
"build": "tsc"
},

Now lets also make use of our SDK to create a post
Run the following command:
npm run build . This command will build your SDK by creating a dist folder
Now run the command tsc
Then run the command: node run.js

You should see the following result log into command line:

SDK-rest-result

The createPost method is called on the client object with a new post object that contains a title, body, and user ID.

When the Promise returned by createPost resolves, a message is logged to the console indicating the ID of the newly created post.

Top comments (0)