# I'm looking for a more elegant way to solve the problem

**URL:** <https://swi-prolog.discourse.group/t/im-looking-for-a-more-elegant-way-to-solve-the-problem/7098>\
**Category:** General\
**Tags:** discussion, how-to, software\
**Created:** [December 21, 2023, 11:01pm UTC](https://swi-prolog.discourse.group/t/im-looking-for-a-more-elegant-way-to-solve-the-problem/7098 "2023-12-21T23:01:49Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![heiheshang](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/heiheshang/32/4419_2.png) [@heiheshang](https://swi-prolog.discourse.group/u/heiheshang)\
**Post date:** [December 21, 2023, 11:01pm UTC](https://swi-prolog.discourse.group/t/im-looking-for-a-more-elegant-way-to-solve-the-problem/7098/1 "2023-12-21T23:01:49Z")

</div>

I’m making wrappers over rest api methods. my code represents similar pieces of code. I’m looking for a generalized method to wrap a rest api

```prolog
'crm.lead.update'(conf(AccessToken, ClientEndpoint), Fields, Reply) :-
    bitrix24_auth:check_token,
    format(atom(Url), '~w~w', [ClientEndpoint, 'crm.lead.update']),
    bearer(AccessToken, Bearer),
    bitrix24_request:post(Url,
         json(
                  Fields
         ),
         Reply,
         [Bearer, status_code(StatusCode)]),
    (200 == StatusCode
        ->
            memberchk(result= @(true), Reply)
        ; debug(http(error), 'error ~q', [Reply])
     ).

```

This code is repeated for all API methods. I’m looking for a way to get rid of this repetition. What if there is a way to write a generalized predicate?

---

<div class="post-metadata">

**Author:** ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)\
**Post date:** [December 22, 2023, 12:03am UTC](https://swi-prolog.discourse.group/t/im-looking-for-a-more-elegant-way-to-solve-the-problem/7098/2 "2023-12-22T00:03:53Z")

</div>

> [@heiheshang](#):
>
> What if there is a way to write a generalized predicate?

Why wouldn’t there be?

Could add another variable to indicate success/failure of the generalized predicate, as an argument.

There’s specifics of how you want to handle failure, debugging info, errors raised, etc.

---

<div class="post-metadata">

**Author:** ![heiheshang](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/heiheshang/32/4419_2.png) [@heiheshang](https://swi-prolog.discourse.group/u/heiheshang)\
**Post date:** [December 22, 2023, 1:52am UTC](https://swi-prolog.discourse.group/t/im-looking-for-a-more-elegant-way-to-solve-the-problem/7098/3 "2023-12-22T01:52:47Z")

</div>

I don’t want to constantly write in code ‘crm.method1’() ‘crm.method2’() ‘crm.methodn’ I will have to wrap all the APIs in my code, how can I transform the call ‘crm.method’ into call (MethodName , args …). if there is no method call will simply fail

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [December 22, 2023, 2:15am UTC](https://swi-prolog.discourse.group/t/im-looking-for-a-more-elegant-way-to-solve-the-problem/7098/4 "2023-12-22T02:15:44Z")

</div>

Is this what you want? call/2

But this will throw an error if the predicate doesn’t exist; you can either set the `unknown` flag appropriately (see current\_prolog\_flag/2) or you can wrap it:

```prolog
catch(call(C,...), error(existence_error(procedure,_),_), fail)

```

---

<div class="post-metadata">

**Author:** ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)\
**Post date:** [December 22, 2023, 2:30am UTC](https://swi-prolog.discourse.group/t/im-looking-for-a-more-elegant-way-to-solve-the-problem/7098/5 "2023-12-22T02:30:31Z")

</div>

> [@heiheshang](#):
>
> ‘crm.method1’() ‘crm.method2’()

Can use term\_expansion/2 to make it elegant.

Kinda-relevant example: [prolog - What would be an elegant/idiomatic way to introduce a predicte on a list of atoms? - Stack Overflow](https://stackoverflow.com/a/77013370/)

---

<div class="post-metadata">

**Author:** ![heiheshang](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/heiheshang/32/4419_2.png) [@heiheshang](https://swi-prolog.discourse.group/u/heiheshang)\
**Post date:** [December 22, 2023, 2:38am UTC](https://swi-prolog.discourse.group/t/im-looking-for-a-more-elegant-way-to-solve-the-problem/7098/6 "2023-12-22T02:38:24Z")

</div>

no, that’s not what I want. Making a wrapper for a third-party rest api is a tedious task. I need a way to write to call ‘rest method’ (args …) in my program code:- predicat('rest method ', args …) I don’t want to implement every third-party rest api method. I need some syntactic sugar for this. I could do function\_post(Method Rest Api , args ) :- http\_client:post() and it works, but I would like to explicitly write ‘Method Rest Api’( in the code. If I explicitly implement each method, it’s a lot of boilerplate code. Explained how could I

---

<div class="post-metadata">

**Author:** ![emiruz](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/emiruz/32/4495_2.png) [@emiruz](https://swi-prolog.discourse.group/u/emiruz)\
**Post date:** [December 22, 2023, 8:12am UTC](https://swi-prolog.discourse.group/t/im-looking-for-a-more-elegant-way-to-solve-the-problem/7098/7 "2023-12-22T08:12:19Z")

</div>

Perhaps you can write down for us in pseudo-code what an ideal result would look like for you? That’d help to make the suggestions more relevant.

---

<div class="post-metadata">

**Author:** ![heiheshang](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/heiheshang/32/4419_2.png) [@heiheshang](https://swi-prolog.discourse.group/u/heiheshang)\
**Post date:** [December 22, 2023, 8:50am UTC](https://swi-prolog.discourse.group/t/im-looking-for-a-more-elegant-way-to-solve-the-problem/7098/8 "2023-12-22T08:50:13Z")

</div>

How do you solve the boilerplate problem?

---

<div class="post-metadata">

**Author:** ![heiheshang](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/heiheshang/32/4419_2.png) [@heiheshang](https://swi-prolog.discourse.group/u/heiheshang)\
**Post date:** [December 22, 2023, 8:55am UTC](https://swi-prolog.discourse.group/t/im-looking-for-a-more-elegant-way-to-solve-the-problem/7098/9 "2023-12-22T08:55:09Z")

</div>

I want to get rid of this code.

```prolog
'crm.lead.update'(conf(AccessToken, ClientEndpoint), Id, Fields) :-
    bitrix24_auth:check_token,
    format(atom(Url), '~w~w', [ClientEndpoint, 'crm.lead.update']),
    bearer(AccessToken, Bearer),
    bitrix24_request:post(Url,
         json(
             json([
                         id = Id,
                         fields = Fields])
         ),
         Reply,
         [Bearer, status_code(StatusCode)]),
    (200 == StatusCode
        ->
            memberchk(result= @(true), Reply)
        ; debug(http(error), 'error ~q', [Reply])
     ).

'crm.lead.get'(conf(AccessToken, ClientEndpoint), Id, Reply) :-
    bitrix24_auth:check_token,
    format(atom(Url), '~w~w', [ClientEndpoint, 'crm.lead.get.json']),
    bearer(AccessToken, Bearer),
    bitrix24_request:post(Url,
         json(
             json([
                         id = Id
                     ])
         ),
         Reply,
         [Bearer]).

'crm.lead.list'(conf(AccessToken, ClientEndpoint), Body, Reply) :-
    bitrix24_auth:check_token,
    format(atom(Url), '~w~w', [ClientEndpoint, 'crm.lead.list.json']),
    bearer(AccessToken, Bearer),
    bitrix24_request:post(Url,
         Body,
         Reply,
         [Bearer]).

'crm.lead.productrows.get'(conf(AccessToken, ClientEndpoint), Body, Reply) :-
    bitrix24_auth:check_token,
    format(atom(Url), '~w~w', [ClientEndpoint, 'crm.lead.productrows.get.json']),
    bearer(AccessToken, Bearer),
    bitrix24_request:post(Url,
                          Body,
                          Reply,
                          [Bearer]).

```

this is how I imagine it

```prolog
Method(conf(AccessToken, ClientEndpoint), Id, Fields) :- call_method(Method, conf(AccessToken, ClientEndpoint), Id, Fields).

```

---

<div class="post-metadata">

**Author:** ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)\
**Post date:** [December 22, 2023, 10:55am UTC](https://swi-prolog.discourse.group/t/im-looking-for-a-more-elegant-way-to-solve-the-problem/7098/10 "2023-12-22T10:55:47Z")

</div>

> [@heiheshang](#):
>
> How do you solve the boilerplate problem?

By writing a program to create your predicates. Simple example:

```prolog
?- assert(mytest(X,Y) :- b(Y,X)).
true.

?- listing(mytest).
:- dynamic mytest/2.

mytest(A, B) :-
    b(B, A).

```

---

<div class="post-metadata">

**Author:** ![ixmrm01](https://avatars.discourse-cdn.com/v4/letter/i/858c86/32.png) [@ixmrm01](https://swi-prolog.discourse.group/u/ixmrm01)\
**Post date:** [December 26, 2023, 7:29pm UTC](https://swi-prolog.discourse.group/t/im-looking-for-a-more-elegant-way-to-solve-the-problem/7098/11 "2023-12-26T19:29:47Z")

</div>

> <https://github.com/terminusdb/terminusdb/blob/0400f4d106daacdf9c54444bf2bf4f7c6a26bc53/src/server/routes.pl#L3260>

> <https://github.com/terminusdb/terminusdb/blob/0400f4d106daacdf9c54444bf2bf4f7c6a26bc53/src/server/routes.pl#L3286>

> <https://github.com/terminusdb/terminusdb/blob/0400f4d106daacdf9c54444bf2bf4f7c6a26bc53/src/server/routes.pl#L3302>

Could this help you?
