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"]
}
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 baseCtors
array.
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:
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:
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)