How to create the Node.js API with TypeScript and GraphQL

GraphQL is a strongly typed query language, and Typescript is a typed superset of JavaScript - together they are a match made in heaven!

Prerequisites

  • Basic knowledge of TypeScript and Node.js
  • You should be able to work with Git

Why GraphQL

GraphQL is a query language for our API. It makes developing complex APIs a breeze by being strongly typed, which allows us to easily generate mocks for tests, documentation and automated optimizations.

GraphQL also allows us to optimize latency and response sizes as we can selectively query data or batch requests very easily. It also allows us to validate the input in several easy ways.

Approaching types

Unfortunately, syncing the types of both GraphQL and TypeScript is not so straight forward, and here are two ways in which we can achieve this:

  • Generating GraphQL from TypeScript using annotations. type-graphql is a library that does just that, but this can pose a problem when you also want to use the types on the front-end.

  • Generating TypeScript from a GraphQL schema. There are a lot of tools for generating types out of the schema such as graphql-schema-typescript.

Before we start

In this tutorial, we will build a simple message board app, and add some basic authentication to it. There will be no database here — we will simply use lowdb to create a database out of a JSON file.

We are going to use a pretty large array of technologies here. Here are some of them:

  • Apollo - Provides us with a server implementation for GraphQL, creates a playground where we can play with our queries and gives us different tools. Apollo can be either a standalone server or combined with Express. We will use the later.

  • graphql-schema-typescript & graphql cli - These two tools will allow us to convert our GraphQL API into TypeScript. They can do more, but that’s mostly what we will use them for.

  • graphql-tag - Allows us to embed chunks of GraphQL code inside our TypeScript files. It makes it easier to separate our schemas into multiple smaller chunks.

We will also use uuid to generates id’s, bcrypt to hash passwords and JWT to generate tokens, but you can ignore these parts as we will not discuss them in this article.

The basics of GraphQL

I think the easiest way to explain how GraphQL schemas work will be to simply check an example.

We will use 3 root types for our schemas:

type Query {
  getPuppies: [Puppy]
}

type Mutation {
  createPuppy(input: InputPuppy!): Puppy
}

type Subscription {
  onPuppy: String
}

Let’s take a look at what we have here:

  • Query - defines all of our queries. As you can see we have a query called getPuppies, and it returns an array of puppies. This is the array notation in GraphQL: [Int] [String] [Cat]…

  • Mutation - defines all of our possible mutations. You can think of it as PUT/POST in terms of REST. As you can see we have a mutation named createPuppy which accepts a Puppy by the name of input. The ! sign after the Puppy means it is required, and it returns a single puppy.

  • Subscription - defines all of the events our server can emit to the client. We can use web-sockets to subscribe to the onPuppy subscription and get a String every time a new puppy is born.

Simple GraphQL queries make use of POST request as follows:

query {
  getPuppies{
    name
    id
  }
  getKittens{
    name
    age
  }
}

This is a good example since it shows how we can batch queries. We will have data from 2 queries, returned in a single HTTP request.

To do such a thing with a REST API we would have to do two requests, one to GET /api/puppies and another to GET /api/kittens. That way the response is simpler, faster, the server needs to handle fewer requests and we have less network overhead for both the clients and the server.

Let’s say a puppy also has color,eyeColor and owner - thanks to GraphQL we don’t have to get those parameters, we can simply query what we need.

We will use some of the types GraphQL provides:

  • type - you can think of type values as objects. We have seen them before and we can also define custom Objects.

  • scalarType - the base scalar Types are Int, Float, Boolean, String and ID which can be either a string or a number, but it’s always parsed as a string.

  • input - input are types that can be accepted as input for queries, the base scalarTypes are also accepted as input for functions.

  • enum - an enum of strings

We can define types like this:

" we can define descriptions too "
    # or comments
    input GetBookInput {
        id: ID!
    }

    " we can also define required on types using !"
    type Book {
        id: ID!
        title: String
        writerID: ID!
        country: CountryEnum
    }


    """
    multiline descriptions
    are also possible
    """
    enum CountryEnum {
      UNITED_STATES
      JAPAN
      CHINA
    }

GraphQL has a lot of other types, and you can read more about them in the official docs. You may want to learn more about GraphQL, and there’s a lot to learn about it, and if that’s the case you should visit the GraphQL website.

Planning our application

Through this tutorial we will make an API that will provide basic functionality for a real-time message board. You will be able to create a user, get a user, get a user’s public data, post messages, get messages, and listen to new messages.

In terms of REST API it might look something like this:

  • POST /user/login (login)
  • POST /user/register (create)
  • GET /user (get publicly available user data)
  • POST /post (post a new post, a user must be logged in for this)
  • GET /post/all (get all the posts)

And a separate logic for web-sockets.

Each post has a userId which allows us to join and know which user posted it.

Other than that, when a user logs in or registers they will get a JWT token which will be used for authentication.

In GraphQL, however, there are no POST/GET/PUT methods. We will replace them with Mutation and Query which use POST for the HTTP request, and Subscription which uses web-sockets under the hood.

Setting Up

You should clone the git repository and we will go over the main parts of the code.

Unfortunately, it’s beyond the scope of the tutorial to get into the Typescript/Webpack configurations in this tutorial, but they are pretty simple and straightforward.

We can also completely ignore the database implementation. You shouldn’t care about it as it’s only there to provide mock data.

We are going to base our app partially off of this article by the Apollo team which gives a simple method to modularize our GreaphQL schemas.

After cloning you should have this directory structure:
This is image title

Other than that we have some configuration files:

.graphqlconfig This file is used by graphql-cli. It was created with the init command.

webpack.config.js, tsconfig.json, tslint.json Standard files to configure our build. I used webpack since it provides us with HMR so development is much faster than with typescript only.

db.json This file holds our database.

You can run the server like so:

# run the server in development mode
npm run dev

You should be able to see the playground at http://localhost:3000/, for now you can ignore it as we will play with the queries at the end of this tutorial.

It should look like this:
This is image title

Our server

We will start from the file src/index.ts — this is where our server initialization is happening:

import { ApolloServer, Config } from 'apollo-server';
import { makeExecutableSchema } from 'graphql-tools';
import { handleGraphQLContext, handleGraphQLSubscriptionContext } from 'src/auth/index';
import { rawSchema } from './graphql';

const port = process.env.PORT || 3000;

// create our schema
const schema = makeExecutableSchema(rawSchema);

// configure the server here
const serverConfig: Config = {
  schema,
  context: handleGraphQLContext,
  subscriptions: {
    onConnect: handleGraphQLSubscriptionContext,
  },
  playground: {
    settings: {
      'editor.theme': 'dark', // change to light if you prefer
      'editor.cursorShape': 'line', // possible values: 'line', 'block', 'underline'
    },
  },
};

// create a new server
const server = new ApolloServer(serverConfig);
server.listen(port).then(({ url }) => {
  console.log(`🚀  Server ready at ${url}`);
});

You can see that we are doing 3 interesting things:

  1. We create a schema with makeExecutableSchema. We will cover the rawSchema variable later, but this executable schema is the optimized version of our GraphQL schema with the resolvers, it matches GraphQL endpoints to functions that return the responses.

  2. We create the configuration for our server, we pass the schema that matches requests to resolvers, a context which is a function that will authenticate the users, and pass the users as a variable to the resolvers.

  3. We create our server with Apollo.

And that’s it. With this we have web-socket support, GraphQL support, auto-generated documentation and a playground to test queries.

Our first schema

In the file src/graphql/index.ts you can see the root schema:

import { mergeRawSchemas } from './utils/mergeRawSchemas';
import { gql } from 'apollo-server';
import schemaShards from './schemaShards';

export const rawSchema = mergeRawSchemas(
  {
    typeDefs: [
      // we create empty main types, we can later extend them in the shards
      gql`
                 type Query {
                    _empty: String
                }

                type Mutation {
                    _empty: String
                }

                type Subscription {
                    _empty: String
                }
            `,
    ],
    resolvers: {},
  },
  schemaShards,
);

We see some new things here too:

gql - a tag used for creating our schema. It should provide syntax highlighting and auto-complete in your IDE of choice.

Each type has a “_empty” field. This is used so we can later extend those types, allowing us to completely modularize our application into different files.

mergeRawSchemas is a utility function written with lodash. It merges the arrays that contain typeDefs and the objects that contain the resolvers.

Now we can look at the users schema, in src/graphql/schemaShards/user, I’m separating the code snippets to allow syntax highlight.

Our schema:

extend type Query {
    " login as a user "
    loginUser(input: InputLogin!): User
    " get a user's public data"
    getUser(id: ID!): PublicUser
}

extend type Mutation {
    " register a new user "
    registerUser(input: InputRegisterUser!): User
}

" used for logging in "
input InputLogin {
    email: String!
    password: String!
}

" used for creating a new user "
input InputRegisterUser {
    name: String!
    email: String!
    password: String!
}

" a type defining a user's public data "
type PublicUser {
    id: ID
    name: String
    email: String
}

" a type defining a user  "
type User {
    id: ID
    name: String
    email: String
    token: String
}

And our code:

import { getPublicUser, getUserByPasswordAndEmail, registerUser } from 'src/db';
import { gql } from 'apollo-server';

const typeDefs = gql`..typedefs..`;

export default {
  resolvers: {
    Query: {
      // login
      loginUser: (root, { input }: GQL.QueryToLoginUserArgs) => getUserByPasswordAndEmail(input),
      // get a user
      getUser: (root, { id }:  GQL.QueryToGetUserArgs) => getPublicUser(id),
    },
    Mutation: {
      // register
      registerUser:  (root, { input }: GQL.MutationToRegisterUserArgs) => registerUser(input),
    },
  },
  typeDefs: [typeDefs],
};

As you can see, for each root type I have created a matching resolver, and each resolver is a function that gets some parameters. It usually looks like this:

fieldName(root, args, context, info) { result }

Where root is used to do type resolution, we will talk about more about it later in this post.

args are the arguments we pass. context is an object that we will handle later when we talk about authentication.

info is a pretty advanced variable. It contains information about the execution. In most cases we don’t need to use it.

And a result can be either a value or a promise that returns the value. The value must match the return value defined in the schema.

Generating types

The types you see such as GQL.QueryToLoginUserArgs are auto generated. Here is how we can generate them.

# download the schema with graphql-cli
graphql get-schema

You will have the schema downloaded and saved in** src/_typedefs/schema.graphql** (it’s defined in .graphqlconfig). I only use it to generate types, but this schema could have different usages.

Now we can generate the types from the schema:

# generate types with graphql-schema-typescript

graphql-schema-typescript --namespace=GQL --global=true --typePrefix='' generate-ts --output=src/__typedefs/graphqlTypes.d.ts src/__typedefs

And with that we are done. We should have a new file named graphqlTypes.d.ts and the types will be available globally under the GQL namespace.

For simplicity it’s all defined in package.json, so generating types is easy – just call npm run generate-typedefs.

Authentication

As I mentioned before, I created a function called handleGraphQLContext. We can take a look at it in src/auth/index.ts:

import { getUserByToken } from 'src/db';
import { Request, Response } from 'express';

// our context interface
export interface IContext {
  token?: string;
}

// handle all of the context magic here
function createContext(token: string): Promise<IContext> | IContext {
  return {
    token,
  };
}

// create context for requests
export function handleGraphQLContext(ctx: {connection?: any, req?: Request, res?: Response}) {
  const { req, connection } = ctx;
  // we already connected with a subscription
  if (connection) {
    return connection.context;
  }
  // check the request for the token
  const token = req.headers && req.headers.token;
  return createContext(token as string);
}

// handle authentication for socket connections
export function handleGraphQLSubscriptionContext(
    connectionParams: {token: string},
    webSocket: WebSocket,
) {
  const token = connectionParams.token;
  return createContext(token);
}

// check if the user is logged in or whatever you want to do to authenticate the user
export async function authenticateContext(context: IContext): Promise<GQL.User> {
  if (!context.token) {
    // too bad 👎
    throw new Error('user is not logged in');
  }
  const user = await getUserByToken(context.token);
  if (!user) {
    // too bad 👎
    throw new Error('invalid token');
  }
  // yay 👍
  return user;
}

Depending on whether the request is a subscription or a query/mutation, we will have to handle it differently. Either way we want to generate the same context, so we handle it with one of the functions handleGraphQLSubscriptionContext or handleGraphQLContext. Those functions extract the token and call createContext.

Our main authentication logic should happen in either createContext or in authenticateContext.

Unfortunately, there is no easy way to do authentication with OAuth or other complicated mechanisms in Apollo, but you can create your own Express app and let apollo-server become a middleware in it. This is easier and pretty straightforward to do.

const app = express();
app.use('/auth', authRoutes);
apolloServer.applyMiddleware({app, path: '/graphql'});
app.listen(3000);

Subscriptions

Now that we can create and get a user, and we can authenticate them, let’s create an API to post, get and listen to new messages.

We need to start by looking at** src/graphql/subscriptionManager.ts**:

import { PubSub } from 'graphql-subscriptions';

// In a production server you might want to have some message broker or pubsub implementation like
// rabbitMQ, redis or kafka logic here
// you can use one of the graphql subscription implementations to do it easily
//
// Redis: https://github.com/davidyaha/graphql-redis-subscriptions
// Kafka: https://github.com/ancashoria/graphql-kafka-subscriptions
// Rabbitmq: https://github.com/cdmbase/graphql-rabbitmq-subscriptions

export const pubsub = new PubSub();

This is the file where you could handle all of the pubsub tools like kafka/reds/rabbitmq. The comments have leads for libraries to help you with that kind of task.

But we are going to use a local pubsub since we are not doing a microservices architecture here.

graphql-subscriptions have lots of other useful tools for managing subscriptions, but we will keep it simple for this tutorial.

Next we will see how to implement a simple subscription:

Let’s take a look at src/graphql/schemaShards/posts.ts. We will first look at the GraphQL schema there:

extend type Query {
    " get all posts "
    getPosts: [Post]
}

extend type Mutation {
    " create a new post "
    createPost(input: InputCreatePost!): Post
}

extend type Subscription {
    " called when a new post is created "
    postCreated: Post
}

" input to create a new post "
input InputCreatePost {
    text: String
    userId: ID
}

type Post {
    id: ID
    userId: ID
    text: String
    user: PublicUser
    timestamp: String
}

As you can see this schema is pretty much the same. We only added a Subscription type, and it has an event named postCreated that returns an object of type Post.

It means that the client can subscribe to this postCreated event and get the new post.

Now we have a pretty simple resolver for our subscription:

Subscription: {
      postCreated: {
        subscribe: (root, args, context) => {
          return pubsub.asyncIterator('postCreated');
        },
      },
    },

But in order for this subscription to do anything, we need to publish to it. We can examine the createPost mutation for that:

Mutation: {
      // create a post
      createPost:  async (root, { input }: GQL.MutationToCreatePostArgs, context) => {
        // get the user from the context
        const user = await authenticateContext(context);
        // create a new post in the database
        const post = await createPost(input, user.id);
        // publish the post to the subscribers
        pubsub.publish('postCreated', {
          postCreated: post,
        });
        return post;
      },
    }

We used the authenticateContext function to get the user from its context. If no user exists, we can just let it throw an error and let Apollo catch it.

For the subscription, we use pubsub.publish. We pass the name of the subscription, and we need to pass an object that has a key with the name of the subscription, and a value of whatever we want the subscription to send.

Type resolvers

Type resolvers are an easy way to emulate an SQL “join” like you may do for the database. GraphQL is designed in a way that enables it to work well with microservices. Let’s pretend we keep the posts in one microservice and the users in another.

You can see that our Post has 2 variables that are useful for us: user and userId.

Post: {
  user: (post: Partial<GQL.Post>) => getPublicUser(post.userId),
},

Instead of a generic root argument we now have a post argument. This is because we now have a type resolver with an actual type. We have a Partial since it is not the full Post object, and we just need to return the user, or a promise for a user.

Playing in the playground

Now we are pretty much done with building our little server. We have good type definitions and are now able to modularize our app. Adding and editing resolvers and our schemas is a breeze.

But what does all of this allow us to do? Let’s take a look at how to work with the playground and how to read the documentation that we created without even knowing.

After you open the playground you can create a new user. The new user requires us to pass in a name, email and a password in order to create it. We can find out how to do it by looking at the documentation.

Click the green button on the right side of the playground (it says SCHEMA).

Click the query you want to use (registerUser in this case).

Click on the arguments or variables (input) in this case.

And you will get more information about the query, what variables it can return, what arguments it accepts, and we can easily write documentation about what each variable does.
This is image title

Let’s create a user now. This is how we pass variables to the playground and you should also have the autocomplete option.

Click the play button to make the query.
This is image title

To understand exactly what the playground sends to the server we can check out the network using the debugger. This is what the request looks like:
This is image title

As you can see, we sent a simple POST request with some variables, a query and an operation name. The operation name can be useful for debugging, but it can have any name you want.

Now to see how our subscription works, we can call it with a simple query and with no variables. As you can see I chose not to return the userId as we don’t need it.

subscription{
  postCreated{
    text
    user{
      name
    }
  }
}

Press the play button, and open another tab. In the other tab we can create a new Post. You need to copy the token from the database and pass it as a header:

Query

mutation createPost($input: InputCreatePost!){
  createPost(input:$input){
    id
    text
    user{
      name
    }
  }
}

Headers (goes into the HTTP HEADERS tab)

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImNjZjQxMDdmLThjOGMtNDBhNy04NzE5LThkZjNjNjI5NDcwNiIsImlhdCI6MTU0OTIxODkwNn0.E8tTQxmzrkHpksgXq0egP4JDjz6N-Lr31PegRc9BJIQ"
}

Variables

{
  "input": {
    "text": "hello world"
  }
}

Now the server should have sent data to the subscription, and it should be updated.

Summary

I hope that this tutorial showed you how easy it is to create a GraphQL server with Apollo, and that synchronizing your TypeScript and schema is not that difficult either.

We can gain so much from using GraphQL in terms of performance, documentation and stability.

Thanks for reading !
Originally published by Liron Navon at hashnode.com

#node-js #typescript #graphql

What is GEEK

Buddha Community

How to create the Node.js API with TypeScript and GraphQL

NBB: Ad-hoc CLJS Scripting on Node.js

Nbb

Not babashka. Node.js babashka!?

Ad-hoc CLJS scripting on Node.js.

Status

Experimental. Please report issues here.

Goals and features

Nbb's main goal is to make it easy to get started with ad hoc CLJS scripting on Node.js.

Additional goals and features are:

  • Fast startup without relying on a custom version of Node.js.
  • Small artifact (current size is around 1.2MB).
  • First class macros.
  • Support building small TUI apps using Reagent.
  • Complement babashka with libraries from the Node.js ecosystem.

Requirements

Nbb requires Node.js v12 or newer.

How does this tool work?

CLJS code is evaluated through SCI, the same interpreter that powers babashka. Because SCI works with advanced compilation, the bundle size, especially when combined with other dependencies, is smaller than what you get with self-hosted CLJS. That makes startup faster. The trade-off is that execution is less performant and that only a subset of CLJS is available (e.g. no deftype, yet).

Usage

Install nbb from NPM:

$ npm install nbb -g

Omit -g for a local install.

Try out an expression:

$ nbb -e '(+ 1 2 3)'
6

And then install some other NPM libraries to use in the script. E.g.:

$ npm install csv-parse shelljs zx

Create a script which uses the NPM libraries:

(ns script
  (:require ["csv-parse/lib/sync$default" :as csv-parse]
            ["fs" :as fs]
            ["path" :as path]
            ["shelljs$default" :as sh]
            ["term-size$default" :as term-size]
            ["zx$default" :as zx]
            ["zx$fs" :as zxfs]
            [nbb.core :refer [*file*]]))

(prn (path/resolve "."))

(prn (term-size))

(println (count (str (fs/readFileSync *file*))))

(prn (sh/ls "."))

(prn (csv-parse "foo,bar"))

(prn (zxfs/existsSync *file*))

(zx/$ #js ["ls"])

Call the script:

$ nbb script.cljs
"/private/tmp/test-script"
#js {:columns 216, :rows 47}
510
#js ["node_modules" "package-lock.json" "package.json" "script.cljs"]
#js [#js ["foo" "bar"]]
true
$ ls
node_modules
package-lock.json
package.json
script.cljs

Macros

Nbb has first class support for macros: you can define them right inside your .cljs file, like you are used to from JVM Clojure. Consider the plet macro to make working with promises more palatable:

(defmacro plet
  [bindings & body]
  (let [binding-pairs (reverse (partition 2 bindings))
        body (cons 'do body)]
    (reduce (fn [body [sym expr]]
              (let [expr (list '.resolve 'js/Promise expr)]
                (list '.then expr (list 'clojure.core/fn (vector sym)
                                        body))))
            body
            binding-pairs)))

Using this macro we can look async code more like sync code. Consider this puppeteer example:

(-> (.launch puppeteer)
      (.then (fn [browser]
               (-> (.newPage browser)
                   (.then (fn [page]
                            (-> (.goto page "https://clojure.org")
                                (.then #(.screenshot page #js{:path "screenshot.png"}))
                                (.catch #(js/console.log %))
                                (.then #(.close browser)))))))))

Using plet this becomes:

(plet [browser (.launch puppeteer)
       page (.newPage browser)
       _ (.goto page "https://clojure.org")
       _ (-> (.screenshot page #js{:path "screenshot.png"})
             (.catch #(js/console.log %)))]
      (.close browser))

See the puppeteer example for the full code.

Since v0.0.36, nbb includes promesa which is a library to deal with promises. The above plet macro is similar to promesa.core/let.

Startup time

$ time nbb -e '(+ 1 2 3)'
6
nbb -e '(+ 1 2 3)'   0.17s  user 0.02s system 109% cpu 0.168 total

The baseline startup time for a script is about 170ms seconds on my laptop. When invoked via npx this adds another 300ms or so, so for faster startup, either use a globally installed nbb or use $(npm bin)/nbb script.cljs to bypass npx.

Dependencies

NPM dependencies

Nbb does not depend on any NPM dependencies. All NPM libraries loaded by a script are resolved relative to that script. When using the Reagent module, React is resolved in the same way as any other NPM library.

Classpath

To load .cljs files from local paths or dependencies, you can use the --classpath argument. The current dir is added to the classpath automatically. So if there is a file foo/bar.cljs relative to your current dir, then you can load it via (:require [foo.bar :as fb]). Note that nbb uses the same naming conventions for namespaces and directories as other Clojure tools: foo-bar in the namespace name becomes foo_bar in the directory name.

To load dependencies from the Clojure ecosystem, you can use the Clojure CLI or babashka to download them and produce a classpath:

$ classpath="$(clojure -A:nbb -Spath -Sdeps '{:aliases {:nbb {:replace-deps {com.github.seancorfield/honeysql {:git/tag "v2.0.0-rc5" :git/sha "01c3a55"}}}}}')"

and then feed it to the --classpath argument:

$ nbb --classpath "$classpath" -e "(require '[honey.sql :as sql]) (sql/format {:select :foo :from :bar :where [:= :baz 2]})"
["SELECT foo FROM bar WHERE baz = ?" 2]

Currently nbb only reads from directories, not jar files, so you are encouraged to use git libs. Support for .jar files will be added later.

Current file

The name of the file that is currently being executed is available via nbb.core/*file* or on the metadata of vars:

(ns foo
  (:require [nbb.core :refer [*file*]]))

(prn *file*) ;; "/private/tmp/foo.cljs"

(defn f [])
(prn (:file (meta #'f))) ;; "/private/tmp/foo.cljs"

Reagent

Nbb includes reagent.core which will be lazily loaded when required. You can use this together with ink to create a TUI application:

$ npm install ink

ink-demo.cljs:

(ns ink-demo
  (:require ["ink" :refer [render Text]]
            [reagent.core :as r]))

(defonce state (r/atom 0))

(doseq [n (range 1 11)]
  (js/setTimeout #(swap! state inc) (* n 500)))

(defn hello []
  [:> Text {:color "green"} "Hello, world! " @state])

(render (r/as-element [hello]))

Promesa

Working with callbacks and promises can become tedious. Since nbb v0.0.36 the promesa.core namespace is included with the let and do! macros. An example:

(ns prom
  (:require [promesa.core :as p]))

(defn sleep [ms]
  (js/Promise.
   (fn [resolve _]
     (js/setTimeout resolve ms))))

(defn do-stuff
  []
  (p/do!
   (println "Doing stuff which takes a while")
   (sleep 1000)
   1))

(p/let [a (do-stuff)
        b (inc a)
        c (do-stuff)
        d (+ b c)]
  (prn d))
$ nbb prom.cljs
Doing stuff which takes a while
Doing stuff which takes a while
3

Also see API docs.

Js-interop

Since nbb v0.0.75 applied-science/js-interop is available:

(ns example
  (:require [applied-science.js-interop :as j]))

(def o (j/lit {:a 1 :b 2 :c {:d 1}}))

(prn (j/select-keys o [:a :b])) ;; #js {:a 1, :b 2}
(prn (j/get-in o [:c :d])) ;; 1

Most of this library is supported in nbb, except the following:

  • destructuring using :syms
  • property access using .-x notation. In nbb, you must use keywords.

See the example of what is currently supported.

Examples

See the examples directory for small examples.

Also check out these projects built with nbb:

API

See API documentation.

Migrating to shadow-cljs

See this gist on how to convert an nbb script or project to shadow-cljs.

Build

Prequisites:

  • babashka >= 0.4.0
  • Clojure CLI >= 1.10.3.933
  • Node.js 16.5.0 (lower version may work, but this is the one I used to build)

To build:

  • Clone and cd into this repo
  • bb release

Run bb tasks for more project-related tasks.

Download Details:
Author: borkdude
Download Link: Download The Source Code
Official Website: https://github.com/borkdude/nbb 
License: EPL-1.0

#node #javascript

Hire Dedicated Node.js Developers - Hire Node.js Developers

If you look at the backend technology used by today’s most popular apps there is one thing you would find common among them and that is the use of NodeJS Framework. Yes, the NodeJS framework is that effective and successful.

If you wish to have a strong backend for efficient app performance then have NodeJS at the backend.

WebClues Infotech offers different levels of experienced and expert professionals for your app development needs. So hire a dedicated NodeJS developer from WebClues Infotech with your experience requirement and expertise.

So what are you waiting for? Get your app developed with strong performance parameters from WebClues Infotech

For inquiry click here: https://www.webcluesinfotech.com/hire-nodejs-developer/

Book Free Interview: https://bit.ly/3dDShFg

#hire dedicated node.js developers #hire node.js developers #hire top dedicated node.js developers #hire node.js developers in usa & india #hire node js development company #hire the best node.js developers & programmers

Aria Barnes

Aria Barnes

1622719015

Why use Node.js for Web Development? Benefits and Examples of Apps

Front-end web development has been overwhelmed by JavaScript highlights for quite a long time. Google, Facebook, Wikipedia, and most of all online pages use JS for customer side activities. As of late, it additionally made a shift to cross-platform mobile development as a main technology in React Native, Nativescript, Apache Cordova, and other crossover devices. 

Throughout the most recent couple of years, Node.js moved to backend development as well. Designers need to utilize a similar tech stack for the whole web project without learning another language for server-side development. Node.js is a device that adjusts JS usefulness and syntax to the backend. 

What is Node.js? 

Node.js isn’t a language, or library, or system. It’s a runtime situation: commonly JavaScript needs a program to work, however Node.js makes appropriate settings for JS to run outside of the program. It’s based on a JavaScript V8 motor that can run in Chrome, different programs, or independently. 

The extent of V8 is to change JS program situated code into machine code — so JS turns into a broadly useful language and can be perceived by servers. This is one of the advantages of utilizing Node.js in web application development: it expands the usefulness of JavaScript, permitting designers to coordinate the language with APIs, different languages, and outside libraries.

What Are the Advantages of Node.js Web Application Development? 

Of late, organizations have been effectively changing from their backend tech stacks to Node.js. LinkedIn picked Node.js over Ruby on Rails since it took care of expanding responsibility better and decreased the quantity of servers by multiple times. PayPal and Netflix did something comparative, just they had a goal to change their design to microservices. We should investigate the motivations to pick Node.JS for web application development and when we are planning to hire node js developers. 

Amazing Tech Stack for Web Development 

The principal thing that makes Node.js a go-to environment for web development is its JavaScript legacy. It’s the most well known language right now with a great many free devices and a functioning local area. Node.js, because of its association with JS, immediately rose in ubiquity — presently it has in excess of 368 million downloads and a great many free tools in the bundle module. 

Alongside prevalence, Node.js additionally acquired the fundamental JS benefits: 

  • quick execution and information preparing; 
  • exceptionally reusable code; 
  • the code is not difficult to learn, compose, read, and keep up; 
  • tremendous asset library, a huge number of free aides, and a functioning local area. 

In addition, it’s a piece of a well known MEAN tech stack (the blend of MongoDB, Express.js, Angular, and Node.js — four tools that handle all vital parts of web application development). 

Designers Can Utilize JavaScript for the Whole Undertaking 

This is perhaps the most clear advantage of Node.js web application development. JavaScript is an unquestionable requirement for web development. Regardless of whether you construct a multi-page or single-page application, you need to know JS well. On the off chance that you are now OK with JavaScript, learning Node.js won’t be an issue. Grammar, fundamental usefulness, primary standards — every one of these things are comparable. 

In the event that you have JS designers in your group, it will be simpler for them to learn JS-based Node than a totally new dialect. What’s more, the front-end and back-end codebase will be basically the same, simple to peruse, and keep up — in light of the fact that they are both JS-based. 

A Quick Environment for Microservice Development 

There’s another motivation behind why Node.js got famous so rapidly. The environment suits well the idea of microservice development (spilling stone monument usefulness into handfuls or many more modest administrations). 

Microservices need to speak with one another rapidly — and Node.js is probably the quickest device in information handling. Among the fundamental Node.js benefits for programming development are its non-obstructing algorithms.

Node.js measures a few demands all at once without trusting that the first will be concluded. Many microservices can send messages to one another, and they will be gotten and addressed all the while. 

Versatile Web Application Development 

Node.js was worked in view of adaptability — its name really says it. The environment permits numerous hubs to run all the while and speak with one another. Here’s the reason Node.js adaptability is better than other web backend development arrangements. 

Node.js has a module that is liable for load adjusting for each running CPU center. This is one of numerous Node.js module benefits: you can run various hubs all at once, and the environment will naturally adjust the responsibility. 

Node.js permits even apportioning: you can part your application into various situations. You show various forms of the application to different clients, in light of their age, interests, area, language, and so on. This builds personalization and diminishes responsibility. Hub accomplishes this with kid measures — tasks that rapidly speak with one another and share a similar root. 

What’s more, Node’s non-hindering solicitation handling framework adds to fast, letting applications measure a great many solicitations. 

Control Stream Highlights

Numerous designers consider nonconcurrent to be one of the two impediments and benefits of Node.js web application development. In Node, at whatever point the capacity is executed, the code consequently sends a callback. As the quantity of capacities develops, so does the number of callbacks — and you end up in a circumstance known as the callback damnation. 

In any case, Node.js offers an exit plan. You can utilize systems that will plan capacities and sort through callbacks. Systems will associate comparable capacities consequently — so you can track down an essential component via search or in an envelope. At that point, there’s no compelling reason to look through callbacks.

 

Final Words

So, these are some of the top benefits of Nodejs in web application development. This is how Nodejs is contributing a lot to the field of web application development. 

I hope now you are totally aware of the whole process of how Nodejs is really important for your web project. If you are looking to hire a node js development company in India then I would suggest that you take a little consultancy too whenever you call. 

Good Luck!

Original Source

#node.js development company in india #node js development company #hire node js developers #hire node.js developers in india #node.js development services #node.js development

Node JS Development Company| Node JS Web Developers-SISGAIN

Top organizations and start-ups hire Node.js developers from SISGAIN for their strategic software development projects in Illinois, USA. On the off chance that you are searching for a first rate innovation to assemble a constant Node.js web application development or a module, Node.js applications are the most appropriate alternative to pick. As Leading Node.js development company, we leverage our profound information on its segments and convey solutions that bring noteworthy business results. For more information email us at hello@sisgain.com

#node.js development services #hire node.js developers #node.js web application development #node.js development company #node js application

sophia tondon

sophia tondon

1625114985

Top 10 NodeJs app Development Companies- ValueCoders

Node.js is a prominent tech trend in the space of web and mobile application development. It has been proven very efficient and useful for a variety of application development. Thus, all business owners are eager to leverage this technology for creating their applications.

Are you striving to develop an application using Node.js? But can’t decide which company to hire for NodeJS app development? Well! Don’t stress over it, as the following list of NodeJS app development companies is going to help you find the best partner.

Let’s take a glance at top NodeJS application development companies to hire developers in 2021 for developing a mind-blowing application solution.

Before enlisting companies, I would like to say that every company has a foundation on which they thrive. Their end goals, qualities, and excellence define their competence. Thus, I prepared this list by considering a number of aspects. While making this list, I have considered the following aspects:

  • Review and rating
  • Enlisted by software peer & forums
  • Hourly price
  • Offered services
  • Year of experience (Average 8+ years)
  • Credibility & Excellence
  • Served clients and more

I believe this list will help you out in choosing the best NodeJS service provider company. So, now let’s explore the top NodeJS developer companies to choose from in 2021.

#1. JSGuru

JSGuru is a top-rated NodeJS app development company with an innovative team of dedicated NodeJS developers engaged in catering best-class UI/UX design, software products, and AWS professional services.

It is a team of one of the most talented developers to hire for all types of innovative solution development, including social media, dating, enterprise, and business-oriented solutions. The company has worked for years with a number of startups and launched a variety of products by collaborating with big-name corporations like T-systems.

If you want to hire NodeJS developers to secure an outstanding application, I would definitely suggest them. They serve in the area of eLearning, FinTech, eCommerce, Telecommunications, Mobile Device Management, and more.

  • Ratings: 4.9/5.0

  • Founded: 2006

  • Headquarters: Banja Luka, Bosnia, and Herzegovina

  • Price: Starting from $50/hour

Visit Website - https://www.valuecoders.com/blog/technology-and-apps/top-node-js-app-development-companies

#node js developer #hire node js developer #hiring node js developers #node js development company #node.js development company #node js development services